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

Loading