From ca8c229c66c720ecb6110f8e94d3da5c4d6eeaf5 Mon Sep 17 00:00:00 2001 From: rajatgarg Date: Thu, 30 Oct 2025 23:40:05 +0530 Subject: [PATCH 1/6] [BAEL-7412] Add code for running multiple tomcat instances --- server-modules/apache-tomcat-2/pom.xml | 53 +++++++++++++++++++ .../com/baeldung/tomcat/AppServerXML.java | 37 +++++++++++++ .../java/com/baeldung/tomcat/DualPort.java | 41 ++++++++++++++ .../java/com/baeldung/tomcat/PortServlet.java | 15 ++++++ .../src/main/resources/server.xml | 13 +++++ .../src/main/resources/static/WEB-INF/web.xml | 31 +++++++++++ .../src/main/resources/static/index.html | 8 +++ 7 files changed, 198 insertions(+) create mode 100644 server-modules/apache-tomcat-2/pom.xml create mode 100644 server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/AppServerXML.java create mode 100644 server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java create mode 100644 server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/PortServlet.java create mode 100644 server-modules/apache-tomcat-2/src/main/resources/server.xml create mode 100644 server-modules/apache-tomcat-2/src/main/resources/static/WEB-INF/web.xml create mode 100644 server-modules/apache-tomcat-2/src/main/resources/static/index.html diff --git a/server-modules/apache-tomcat-2/pom.xml b/server-modules/apache-tomcat-2/pom.xml new file mode 100644 index 000000000000..99667e3b3781 --- /dev/null +++ b/server-modules/apache-tomcat-2/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + com.baeldung + server-modules + 1.0.0-SNAPSHOT + + + apache-tomcat-2 + + + + org.apache.tomcat + tomcat-catalina + ${tomcat.version} + + + + org.apache.tomcat + tomcat-juli + ${tomcat.version} + + + + jakarta.servlet + jakarta.servlet-api + 6.0.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + 11 + 11 + + + + + + + 10.1.24 + UTF-8 + + + \ No newline at end of file diff --git a/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/AppServerXML.java b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/AppServerXML.java new file mode 100644 index 000000000000..8c3fed289bcd --- /dev/null +++ b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/AppServerXML.java @@ -0,0 +1,37 @@ +package com.baeldung.tomcat; + +import org.apache.catalina.startup.Catalina; +import java.nio.file.*; + +public class AppServerXML { + + public static void main(String[] args) throws Exception { + Path staticDir = resolvePath("src/main/resources/static"); + Path serverXml = resolvePath("src/main/resources/server.xml"); + Path baseDir = Paths.get("target/tomcat-base").toAbsolutePath(); + + Files.createDirectories(baseDir); + String config = Files.readString(serverXml) + .replace("STATIC_DIR_PLACEHOLDER", staticDir.toString()); + Path configFile = baseDir.resolve("server.xml"); + Files.writeString(configFile, config); + + System.setProperty("catalina.base", baseDir.toString()); + System.setProperty("catalina.home", baseDir.toString()); + + Catalina catalina = new Catalina(); + catalina.load(new String[]{"-config", configFile.toString()}); + catalina.start(); + + System.out.println("\nTomcat started with multiple connectors!"); + System.out.println("http://localhost:8081"); + System.out.println("http://localhost:7081"); + catalina.getServer().await(); + } + + private static Path resolvePath(String relativePath) { + Path path = Paths.get(relativePath); + return Files.exists(path) ? path.toAbsolutePath() + : Paths.get("apache-tomcat-2", relativePath).toAbsolutePath(); + } +} diff --git a/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java new file mode 100644 index 000000000000..63a703c0292c --- /dev/null +++ b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java @@ -0,0 +1,41 @@ +package com.baeldung.tomcat; + +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.apache.catalina.connector.Connector; +import java.io.File; +import java.io.IOException; + +import org.apache.catalina.Context; +import org.apache.catalina.startup.Tomcat; + +public class DualPort { + public static void main(String[] args) throws Exception { + Tomcat tomcat = new Tomcat(); + tomcat.setBaseDir(new File("tomcat-temp").getAbsolutePath()); + + tomcat.setPort(7080); + tomcat.getConnector(); + + Connector secondConnector = new Connector(); + secondConnector.setPort(8080); + tomcat.getService().addConnector(secondConnector); + + Context ctx = tomcat.addContext("", new File(".").getAbsolutePath()); + Tomcat.addServlet(ctx, "portServlet", new HttpServlet() { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + int port = req.getLocalPort(); + resp.setContentType("text/plain"); + resp.getWriter().write("Port: " + port + "\n"); + } + }); + ctx.addServletMappingDecoded("/", "portServlet"); + + tomcat.start(); + System.out.println("✅ Tomcat running on ports 8080 and 7080"); + tomcat.getServer().await(); + } +} + diff --git a/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/PortServlet.java b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/PortServlet.java new file mode 100644 index 000000000000..26c270eea7e1 --- /dev/null +++ b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/PortServlet.java @@ -0,0 +1,15 @@ +package com.baeldung.tomcat; + +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class PortServlet extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + int port = req.getLocalPort(); + resp.setContentType("text/plain"); + resp.getWriter().write("port number: " + port); + } +} diff --git a/server-modules/apache-tomcat-2/src/main/resources/server.xml b/server-modules/apache-tomcat-2/src/main/resources/server.xml new file mode 100644 index 000000000000..e7ff58768098 --- /dev/null +++ b/server-modules/apache-tomcat-2/src/main/resources/server.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/server-modules/apache-tomcat-2/src/main/resources/static/WEB-INF/web.xml b/server-modules/apache-tomcat-2/src/main/resources/static/WEB-INF/web.xml new file mode 100644 index 000000000000..af405ef375f3 --- /dev/null +++ b/server-modules/apache-tomcat-2/src/main/resources/static/WEB-INF/web.xml @@ -0,0 +1,31 @@ + + + + Static HTML Application + + + + default + org.apache.catalina.servlets.DefaultServlet + + listings + false + + 1 + + + + default + / + + + + + index.html + + + diff --git a/server-modules/apache-tomcat-2/src/main/resources/static/index.html b/server-modules/apache-tomcat-2/src/main/resources/static/index.html new file mode 100644 index 000000000000..c644aa338438 --- /dev/null +++ b/server-modules/apache-tomcat-2/src/main/resources/static/index.html @@ -0,0 +1,8 @@ + + +Dual Port Test + +

Tomcat is running!

+

Port:

+ + From 2d7ed3d7a4957b7be6a9019133a024fa82d07024 Mon Sep 17 00:00:00 2001 From: rajatgarg Date: Thu, 30 Oct 2025 23:41:16 +0530 Subject: [PATCH 2/6] [BAEL-7412] Remove Symbol --- .../src/main/java/com/baeldung/tomcat/DualPort.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java index 63a703c0292c..d960398235cd 100644 --- a/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java +++ b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java @@ -34,7 +34,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO ctx.addServletMappingDecoded("/", "portServlet"); tomcat.start(); - System.out.println("✅ Tomcat running on ports 8080 and 7080"); + System.out.println("Tomcat running on ports 8080 and 7080"); tomcat.getServer().await(); } } From 5dec7a423ba454c54d3f5deda2106e2e6030ac6f Mon Sep 17 00:00:00 2001 From: rajatgarg Date: Sun, 2 Nov 2025 19:25:59 +0530 Subject: [PATCH 3/6] [BAEL-7412] Add new module --- server-modules/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/server-modules/pom.xml b/server-modules/pom.xml index 8bbe42aaeefc..1a299aa3128f 100644 --- a/server-modules/pom.xml +++ b/server-modules/pom.xml @@ -19,6 +19,7 @@ undertow wildfly armeria + apache-tomcat-2 \ No newline at end of file From a8a4bf595573f14f30c53c167b46412dbd85d58e Mon Sep 17 00:00:00 2001 From: rajatgarg Date: Mon, 10 Nov 2025 01:17:01 +0530 Subject: [PATCH 4/6] [BAEL-7412] Add unit tests --- server-modules/apache-tomcat-2/pom.xml | 13 ++ .../com/baeldung/tomcat/AppServerXML.java | 38 +++-- .../java/com/baeldung/tomcat/DualPort.java | 11 +- .../baeldung/tomcat/AppServerXMLUnitTest.java | 110 +++++++++++++ .../com/baeldung/tomcat/DualPortTest.java | 151 ++++++++++++++++++ 5 files changed, 309 insertions(+), 14 deletions(-) create mode 100644 server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/AppServerXMLUnitTest.java create mode 100644 server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortTest.java diff --git a/server-modules/apache-tomcat-2/pom.xml b/server-modules/apache-tomcat-2/pom.xml index 99667e3b3781..3541efca4e1a 100644 --- a/server-modules/apache-tomcat-2/pom.xml +++ b/server-modules/apache-tomcat-2/pom.xml @@ -29,6 +29,14 @@ jakarta.servlet-api 6.0.0 + + + + org.junit.jupiter + junit-jupiter + 5.10.0 + test + @@ -42,6 +50,11 @@ 11 + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0 + diff --git a/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/AppServerXML.java b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/AppServerXML.java index 8c3fed289bcd..14187f7e8c26 100644 --- a/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/AppServerXML.java +++ b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/AppServerXML.java @@ -1,18 +1,37 @@ package com.baeldung.tomcat; import org.apache.catalina.startup.Catalina; +import java.io.InputStream; +import java.net.URL; import java.nio.file.*; public class AppServerXML { public static void main(String[] args) throws Exception { - Path staticDir = resolvePath("src/main/resources/static"); - Path serverXml = resolvePath("src/main/resources/server.xml"); - Path baseDir = Paths.get("target/tomcat-base").toAbsolutePath(); + AppServerXML app = new AppServerXML(); + Catalina catalina = app.startServer(); + catalina.getServer().await(); + } + public Catalina startServer() throws Exception { + URL staticUrl = getClass().getClassLoader().getResource("static"); + if (staticUrl == null) { + throw new IllegalStateException("Static directory not found in classpath"); + } + Path staticDir = Paths.get(staticUrl.toURI()); + + Path baseDir = Paths.get("target/tomcat-base").toAbsolutePath(); Files.createDirectories(baseDir); - String config = Files.readString(serverXml) - .replace("STATIC_DIR_PLACEHOLDER", staticDir.toString()); + + String config; + try (InputStream serverXmlStream = getClass().getClassLoader().getResourceAsStream("server.xml")) { + if (serverXmlStream == null) { + throw new IllegalStateException("server.xml not found in classpath"); + } + config = new String(serverXmlStream.readAllBytes()) + .replace("STATIC_DIR_PLACEHOLDER", staticDir.toString()); + } + Path configFile = baseDir.resolve("server.xml"); Files.writeString(configFile, config); @@ -26,12 +45,7 @@ public static void main(String[] args) throws Exception { System.out.println("\nTomcat started with multiple connectors!"); System.out.println("http://localhost:8081"); System.out.println("http://localhost:7081"); - catalina.getServer().await(); - } - - private static Path resolvePath(String relativePath) { - Path path = Paths.get(relativePath); - return Files.exists(path) ? path.toAbsolutePath() - : Paths.get("apache-tomcat-2", relativePath).toAbsolutePath(); + + return catalina; } } diff --git a/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java index d960398235cd..972ff4de094c 100644 --- a/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java +++ b/server-modules/apache-tomcat-2/src/main/java/com/baeldung/tomcat/DualPort.java @@ -11,7 +11,14 @@ import org.apache.catalina.startup.Tomcat; public class DualPort { + public static void main(String[] args) throws Exception { + DualPort dualPort = new DualPort(); + Tomcat tomcat = dualPort.startServer(); + tomcat.getServer().await(); + } + + public Tomcat startServer() throws Exception { Tomcat tomcat = new Tomcat(); tomcat.setBaseDir(new File("tomcat-temp").getAbsolutePath()); @@ -35,7 +42,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO tomcat.start(); System.out.println("Tomcat running on ports 8080 and 7080"); - tomcat.getServer().await(); + + return tomcat; } } - diff --git a/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/AppServerXMLUnitTest.java b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/AppServerXMLUnitTest.java new file mode 100644 index 000000000000..a9ced529e91f --- /dev/null +++ b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/AppServerXMLUnitTest.java @@ -0,0 +1,110 @@ +package com.baeldung.tomcat; + +import org.apache.catalina.startup.Catalina; +import org.junit.jupiter.api.*; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.*; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class AppServerXMLUnitTest { + + private static AppServerXML app; + private static Catalina catalina; + private static final int HTTP_PORT_1 = 8081; + private static final int HTTP_PORT_2 = 7081; + + @BeforeAll + static void setUp() throws Exception { + app = new AppServerXML(); + catalina = app.startServer(); + Thread.sleep(2000); + } + + @AfterAll + static void shutDown() throws Exception { + if (catalina != null && catalina.getServer() != null) { + catalina.stop(); + Thread.sleep(1000); + } + } + + @Test + void givenMultipleConnectors_whenServerStarts_thenContainsMultiplePorts() { + assertNotNull(catalina.getServer(), "Server should be initialized"); + + Path configFile = Paths.get("target/tomcat-base/server.xml"); + assertTrue(Files.exists(configFile), "Generated server.xml should exist"); + + assertDoesNotThrow(() -> { + String config = Files.readString(configFile); + assertTrue(config.contains("port=\"8081\""), "Config should have port 8081"); + assertTrue(config.contains("port=\"7081\""), "Config should have port 7081"); + assertFalse(config.contains("STATIC_DIR_PLACEHOLDER"), "Placeholder should be replaced"); + }); + } + + @Test + void givenMultipleConnectors_whenResponds_thenReturns200() { + assertDoesNotThrow(() -> { + int response1 = getResponseCode(HTTP_PORT_1); + int response2 = getResponseCode(HTTP_PORT_2); + + assertEquals(200, response1, "Port 8081 should respond with 200 OK"); + assertEquals(200, response2, "Port 7081 should respond with 200 OK"); + }); + } + + @Test + void givenMultipleConnectors_whenResponds_thenReturnsIdenticalContent() { + assertDoesNotThrow(() -> { + String content1 = getContent(HTTP_PORT_1); + String content2 = getContent(HTTP_PORT_2); + + assertNotNull(content1, "Content from port 8081 should not be null"); + assertNotNull(content2, "Content from port 7081 should not be null"); + + assertTrue(content1.contains("Tomcat is running"), "Content should contain expected text"); + assertEquals(content1, content2, "Both ports should serve identical content"); + }); + } + + private int getResponseCode(int port) throws Exception { + HttpURLConnection connection = getConnection(port); + try { + return connection.getResponseCode(); + } finally { + connection.disconnect(); + } + } + + private String getContent(int port) throws Exception { + HttpURLConnection connection = getConnection(port); + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(connection.getInputStream()))) { + return reader.lines().collect(Collectors.joining()); + } finally { + connection.disconnect(); + } + } + + private HttpURLConnection getConnection(int port) throws IOException { + URL url = URI.create("http://localhost:" + port + "/").toURL(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + return connection; + } +} + diff --git a/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortTest.java b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortTest.java new file mode 100644 index 000000000000..afbf6b2c9d61 --- /dev/null +++ b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortTest.java @@ -0,0 +1,151 @@ +package com.baeldung.tomcat; + +import org.apache.catalina.connector.Connector; +import org.apache.catalina.startup.Tomcat; +import org.junit.jupiter.api.*; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.*; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +class DualPortTest { + + private static DualPort app; + private static Tomcat tomcat; + private static final int PORT_1 = 8080; + private static final int PORT_2 = 7080; + + @BeforeAll + static void setUp() throws Exception { + app = new DualPort(); + tomcat = app.startServer(); + Thread.sleep(2000); // Wait for server to fully start + } + + @AfterAll + static void tearDown() throws Exception { + if (tomcat != null && tomcat.getServer() != null) { + tomcat.stop(); + tomcat.destroy(); + Thread.sleep(1000); + } + } + + @Test + @Order(1) + @DisplayName("Should start Tomcat with two connectors programmatically") + void testServerStartsWithTwoConnectors() { + assertNotNull(tomcat, "Tomcat instance should not be null"); + assertNotNull(tomcat.getServer(), "Server should be initialized"); + + // Verify two connectors are configured + Connector[] connectors = tomcat.getService().findConnectors(); + assertEquals(2, connectors.length, "Should have exactly 2 connectors"); + + // Verify ports + int[] ports = new int[]{connectors[0].getPort(), connectors[1].getPort()}; + assertTrue(contains(ports, 8080), "Should have connector on port 8080"); + assertTrue(contains(ports, 7080), "Should have connector on port 7080"); + } + + @Test + @Order(2) + @DisplayName("Both connectors should respond with HTTP 200") + void testBothConnectorsRespond() { + assertDoesNotThrow(() -> { + int response1 = getResponseCode(PORT_1); + int response2 = getResponseCode(PORT_2); + + assertEquals(200, response1, "Port 8080 should respond with 200 OK"); + assertEquals(200, response2, "Port 7080 should respond with 200 OK"); + }); + } + + @Test + @Order(3) + @DisplayName("Each connector should report its own port number") + void testEachConnectorReportsCorrectPort() { + assertDoesNotThrow(() -> { + String content1 = getContent(PORT_1); + String content2 = getContent(PORT_2); + + assertNotNull(content1, "Content from port 8080 should not be null"); + assertNotNull(content2, "Content from port 7080 should not be null"); + + // Each port should report its own port number + assertTrue(content1.contains("Port: 8080"), + "Port 8080 should report 'Port: 8080', but got: " + content1); + assertTrue(content2.contains("Port: 7080"), + "Port 7080 should report 'Port: 7080', but got: " + content2); + + // Content should be different (showing different ports) + assertNotEquals(content1, content2, + "Each port should report its own port number - content should differ"); + }); + } + + @Test + @Order(4) + @DisplayName("Servlet should return plain text content type") + void testServletContentType() { + assertDoesNotThrow(() -> { + URL url = URI.create("http://localhost:" + PORT_1 + "/").toURL(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + + try { + String contentType = connection.getContentType(); + assertNotNull(contentType, "Content type should not be null"); + assertTrue(contentType.contains("text/plain"), + "Content type should be text/plain, but got: " + contentType); + } finally { + connection.disconnect(); + } + }); + } + + // Helper methods + private boolean contains(int[] array, int value) { + for (int i : array) { + if (i == value) return true; + } + return false; + } + + private int getResponseCode(int port) throws Exception { + URL url = URI.create("http://localhost:" + port + "/").toURL(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + + try { + return connection.getResponseCode(); + } finally { + connection.disconnect(); + } + } + + private String getContent(int port) throws Exception { + URL url = URI.create("http://localhost:" + port + "/").toURL(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(connection.getInputStream()))) { + return reader.lines().collect(Collectors.joining()); + } finally { + connection.disconnect(); + } + } +} + From f905f501c6a487286f75d74339f6bdbc1814ea74 Mon Sep 17 00:00:00 2001 From: rajatgarg Date: Tue, 11 Nov 2025 03:03:11 +0530 Subject: [PATCH 5/6] [BAEL-7412] Refactor and fix naming --- ....java => AppServerXMLIntegrationTest.java} | 40 +---- .../tomcat/DualPortIntegrationTest.java | 80 ++++++++++ .../com/baeldung/tomcat/DualPortTest.java | 151 ------------------ .../com/baeldung/tomcat/HttpConnection.java | 38 +++++ 4 files changed, 121 insertions(+), 188 deletions(-) rename server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/{AppServerXMLUnitTest.java => AppServerXMLIntegrationTest.java} (65%) create mode 100644 server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortIntegrationTest.java delete mode 100644 server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortTest.java create mode 100644 server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/HttpConnection.java diff --git a/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/AppServerXMLUnitTest.java b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/AppServerXMLIntegrationTest.java similarity index 65% rename from server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/AppServerXMLUnitTest.java rename to server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/AppServerXMLIntegrationTest.java index a9ced529e91f..3edcba0d2c44 100644 --- a/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/AppServerXMLUnitTest.java +++ b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/AppServerXMLIntegrationTest.java @@ -3,21 +3,15 @@ import org.apache.catalina.startup.Catalina; import org.junit.jupiter.api.*; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.stream.Collectors; +import static com.baeldung.tomcat.HttpConnection.getContent; +import static com.baeldung.tomcat.HttpConnection.getResponseCode; import static org.junit.jupiter.api.Assertions.*; -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -public class AppServerXMLUnitTest { +public class AppServerXMLIntegrationTest { private static AppServerXML app; private static Catalina catalina; @@ -78,33 +72,5 @@ void givenMultipleConnectors_whenResponds_thenReturnsIdenticalContent() { assertEquals(content1, content2, "Both ports should serve identical content"); }); } - - private int getResponseCode(int port) throws Exception { - HttpURLConnection connection = getConnection(port); - try { - return connection.getResponseCode(); - } finally { - connection.disconnect(); - } - } - - private String getContent(int port) throws Exception { - HttpURLConnection connection = getConnection(port); - try (BufferedReader reader = new BufferedReader( - new InputStreamReader(connection.getInputStream()))) { - return reader.lines().collect(Collectors.joining()); - } finally { - connection.disconnect(); - } - } - - private HttpURLConnection getConnection(int port) throws IOException { - URL url = URI.create("http://localhost:" + port + "/").toURL(); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setConnectTimeout(5000); - connection.setReadTimeout(5000); - return connection; - } } diff --git a/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortIntegrationTest.java b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortIntegrationTest.java new file mode 100644 index 000000000000..fb37aa92861c --- /dev/null +++ b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortIntegrationTest.java @@ -0,0 +1,80 @@ +package com.baeldung.tomcat; + +import org.apache.catalina.connector.Connector; +import org.apache.catalina.startup.Tomcat; +import org.junit.jupiter.api.*; + +import static com.baeldung.tomcat.HttpConnection.getContent; +import static com.baeldung.tomcat.HttpConnection.getResponseCode; +import static org.junit.jupiter.api.Assertions.*; + +class DualPortIntegrationTest { + + private static DualPort app; + private static Tomcat tomcat; + private static final int PORT_1 = 8080; + private static final int PORT_2 = 7080; + + @BeforeAll + static void setUp() throws Exception { + app = new DualPort(); + tomcat = app.startServer(); + Thread.sleep(2000); + } + + @AfterAll + static void tearDown() throws Exception { + if (tomcat != null && tomcat.getServer() != null) { + tomcat.stop(); + tomcat.destroy(); + Thread.sleep(1000); + } + } + + @Test + void givenMultipleConnectors_whenServerStarts_thenContainsMultiplePorts() { + assertNotNull(tomcat, "Tomcat instance should not be null"); + assertNotNull(tomcat.getServer(), "Server should be initialized"); + + Connector[] connectors = tomcat.getService().findConnectors(); + assertEquals(2, connectors.length, "Should have exactly 2 connectors"); + + int[] ports = new int[]{connectors[0].getPort(), connectors[1].getPort()}; + assertTrue(contains(ports, 8080), "Should have connector on port 8080"); + assertTrue(contains(ports, 7080), "Should have connector on port 7080"); + } + + @Test + void givenMultipleConnectors_whenResponds_thenReturns200() { + assertDoesNotThrow(() -> { + int response1 = getResponseCode(PORT_1); + int response2 = getResponseCode(PORT_2); + + assertEquals(200, response1, "Port 8080 should respond with 200 OK"); + assertEquals(200, response2, "Port 7080 should respond with 200 OK"); + }); + } + + @Test + void givenMultipleConnectors_whenResponds_thenReturnsCorrectPort() { + assertDoesNotThrow(() -> { + String content1 = getContent(PORT_1); + String content2 = getContent(PORT_2); + + assertNotNull(content1, "Content from port 8080 should not be null"); + assertNotNull(content2, "Content from port 7080 should not be null"); + + assertTrue(content1.contains("Port: 8080"), "Port 8080 should report 'Port: 8080', but got: " + content1); + assertTrue(content2.contains("Port: 7080"), "Port 7080 should report 'Port: 7080', but got: " + content2); + assertNotEquals(content1, content2, "Each port should report its own port number - content should differ"); + }); + } + + private boolean contains(int[] array, int value) { + for (int i : array) { + if (i == value) return true; + } + return false; + } +} + diff --git a/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortTest.java b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortTest.java deleted file mode 100644 index afbf6b2c9d61..000000000000 --- a/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortTest.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.baeldung.tomcat; - -import org.apache.catalina.connector.Connector; -import org.apache.catalina.startup.Tomcat; -import org.junit.jupiter.api.*; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URL; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.*; - -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -class DualPortTest { - - private static DualPort app; - private static Tomcat tomcat; - private static final int PORT_1 = 8080; - private static final int PORT_2 = 7080; - - @BeforeAll - static void setUp() throws Exception { - app = new DualPort(); - tomcat = app.startServer(); - Thread.sleep(2000); // Wait for server to fully start - } - - @AfterAll - static void tearDown() throws Exception { - if (tomcat != null && tomcat.getServer() != null) { - tomcat.stop(); - tomcat.destroy(); - Thread.sleep(1000); - } - } - - @Test - @Order(1) - @DisplayName("Should start Tomcat with two connectors programmatically") - void testServerStartsWithTwoConnectors() { - assertNotNull(tomcat, "Tomcat instance should not be null"); - assertNotNull(tomcat.getServer(), "Server should be initialized"); - - // Verify two connectors are configured - Connector[] connectors = tomcat.getService().findConnectors(); - assertEquals(2, connectors.length, "Should have exactly 2 connectors"); - - // Verify ports - int[] ports = new int[]{connectors[0].getPort(), connectors[1].getPort()}; - assertTrue(contains(ports, 8080), "Should have connector on port 8080"); - assertTrue(contains(ports, 7080), "Should have connector on port 7080"); - } - - @Test - @Order(2) - @DisplayName("Both connectors should respond with HTTP 200") - void testBothConnectorsRespond() { - assertDoesNotThrow(() -> { - int response1 = getResponseCode(PORT_1); - int response2 = getResponseCode(PORT_2); - - assertEquals(200, response1, "Port 8080 should respond with 200 OK"); - assertEquals(200, response2, "Port 7080 should respond with 200 OK"); - }); - } - - @Test - @Order(3) - @DisplayName("Each connector should report its own port number") - void testEachConnectorReportsCorrectPort() { - assertDoesNotThrow(() -> { - String content1 = getContent(PORT_1); - String content2 = getContent(PORT_2); - - assertNotNull(content1, "Content from port 8080 should not be null"); - assertNotNull(content2, "Content from port 7080 should not be null"); - - // Each port should report its own port number - assertTrue(content1.contains("Port: 8080"), - "Port 8080 should report 'Port: 8080', but got: " + content1); - assertTrue(content2.contains("Port: 7080"), - "Port 7080 should report 'Port: 7080', but got: " + content2); - - // Content should be different (showing different ports) - assertNotEquals(content1, content2, - "Each port should report its own port number - content should differ"); - }); - } - - @Test - @Order(4) - @DisplayName("Servlet should return plain text content type") - void testServletContentType() { - assertDoesNotThrow(() -> { - URL url = URI.create("http://localhost:" + PORT_1 + "/").toURL(); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setConnectTimeout(5000); - - try { - String contentType = connection.getContentType(); - assertNotNull(contentType, "Content type should not be null"); - assertTrue(contentType.contains("text/plain"), - "Content type should be text/plain, but got: " + contentType); - } finally { - connection.disconnect(); - } - }); - } - - // Helper methods - private boolean contains(int[] array, int value) { - for (int i : array) { - if (i == value) return true; - } - return false; - } - - private int getResponseCode(int port) throws Exception { - URL url = URI.create("http://localhost:" + port + "/").toURL(); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setConnectTimeout(5000); - connection.setReadTimeout(5000); - - try { - return connection.getResponseCode(); - } finally { - connection.disconnect(); - } - } - - private String getContent(int port) throws Exception { - URL url = URI.create("http://localhost:" + port + "/").toURL(); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setConnectTimeout(5000); - connection.setReadTimeout(5000); - - try (BufferedReader reader = new BufferedReader( - new InputStreamReader(connection.getInputStream()))) { - return reader.lines().collect(Collectors.joining()); - } finally { - connection.disconnect(); - } - } -} - diff --git a/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/HttpConnection.java b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/HttpConnection.java new file mode 100644 index 000000000000..479820733778 --- /dev/null +++ b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/HttpConnection.java @@ -0,0 +1,38 @@ +package com.baeldung.tomcat; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; +import java.util.stream.Collectors; + +public class HttpConnection { + static int getResponseCode(int port) throws Exception { + HttpURLConnection connection = getConnection(port); + try { + return connection.getResponseCode(); + } finally { + connection.disconnect(); + } + } + + static String getContent(int port) throws Exception { + HttpURLConnection connection = getConnection(port); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { + return reader.lines().collect(Collectors.joining()); + } finally { + connection.disconnect(); + } + } + + static HttpURLConnection getConnection(int port) throws IOException { + URL url = URI.create("http://localhost:" + port + "/").toURL(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + return connection; + } +} From 62f9c4781172b9e26002a4618858f77c7855c0ed Mon Sep 17 00:00:00 2001 From: rajatgarg Date: Tue, 11 Nov 2025 03:04:26 +0530 Subject: [PATCH 6/6] [BAEL-7412] Fix public keyword --- .../test/java/com/baeldung/tomcat/DualPortIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortIntegrationTest.java b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortIntegrationTest.java index fb37aa92861c..cc263724cd46 100644 --- a/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortIntegrationTest.java +++ b/server-modules/apache-tomcat-2/src/test/java/com/baeldung/tomcat/DualPortIntegrationTest.java @@ -8,7 +8,7 @@ import static com.baeldung.tomcat.HttpConnection.getResponseCode; import static org.junit.jupiter.api.Assertions.*; -class DualPortIntegrationTest { +public class DualPortIntegrationTest { private static DualPort app; private static Tomcat tomcat;