Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions server-modules/apache-tomcat-2/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>server-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<artifactId>apache-tomcat-2</artifactId>

<dependencies>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>${tomcat.version}</version>
</dependency>

<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-juli</artifactId>
<version>${tomcat.version}</version>
</dependency>

<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
</dependency>

<!-- Test Dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</build>

<properties>
<tomcat.version>10.1.24</tomcat.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
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 {
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;
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);

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");

return catalina;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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 {
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());

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");

return tomcat;
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
13 changes: 13 additions & 0 deletions server-modules/apache-tomcat-2/src/main/resources/server.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="8081" protocol="HTTP/1.1" />
<Connector port="7081" protocol="HTTP/1.1" />

<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="/tmp/tomcat-dummy" unpackWARs="false" autoDeploy="false">
<Context path="" docBase="STATIC_DIR_PLACEHOLDER" reloadable="false" />
</Host>
</Engine>
</Service>
</Server>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
version="6.0">

<display-name>Static HTML Application</display-name>

<!-- Default servlet for serving static content -->
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<!-- Welcome files -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head><title>Dual Port Test</title></head>
<body>
<h1>Tomcat is running!</h1>
<p>Port: <script>document.write(window.location.port)</script></p>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.baeldung.tomcat;

import org.apache.catalina.startup.Catalina;
import org.junit.jupiter.api.*;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static com.baeldung.tomcat.HttpConnection.getContent;
import static com.baeldung.tomcat.HttpConnection.getResponseCode;
import static org.junit.jupiter.api.Assertions.*;

public class AppServerXMLIntegrationTest {

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");
});
}
}

Original file line number Diff line number Diff line change
@@ -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.*;

public 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;
}
}

Loading