Well, today I’m going to tell something about Apache Tomcat. Apache Tomcat, often referred to as Tomcat Server, is an open-source Java Servlet Container developed by the Apache Software Foundation (ASF). Tomcat implements several Java EE specifications including Java Servlet, JavaServer Pages (JSP), Java EL, and WebSocket, and provides a “pure Java” HTTP web server environment in which Java code can run.
When you develop a web application it would be great if we could embed Apache Tomcat instead of having a separate server. Please note that I learnt this by referring this[3] git repository.
Prerequisites
- Basic Java knowledge, including an installed version of the JVM and Maven.
- Basic knowledge on Spring framework.
Create your pom.xml
Create a folder to hold your app and create a file called pom.xml in the root of that folder with the following contents:
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.rnavagamuwa.sample</groupId> <artifactId>embeddedTomcatSample</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>embeddedTomcatSample Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <tomcat.version>8.0.28</tomcat.version> </properties> <dependencies> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-logging-juli</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper-el</artifactId> <version>${tomcat.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jsp-api</artifactId> <version>${tomcat.version}</version> </dependency> </dependencies> <build> <finalName>embeddedTomcatSample</finalName> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>appassembler-maven-plugin</artifactId> <version>1.1.1</version> <configuration> <assembleDirectory>target</assembleDirectory> <programs> <program> <mainClass>launch.Main</mainClass> <name>webapp</name> </program> </programs> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>assemble</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
There is also a single plugin defined. The appassembler plugin generates a launch script that automatically sets up your classpath and calls your main method (created below) to launch your application.
Add a launcher class
package launch; import java.io.File; import org.apache.catalina.WebResourceRoot; import org.apache.catalina.core.StandardContext; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.webresources.DirResourceSet; import org.apache.catalina.webresources.StandardRoot; public class Main { public static void main(String[] args) throws Exception { String webappDirLocation = "src/main/webapp/"; Tomcat tomcat = new Tomcat(); //The port that we should run on can be set into an environment variable //Look for that variable and default to 8080 if it isn't there. String webPort = System.getenv("PORT"); if(webPort == null || webPort.isEmpty()) { webPort = "8080"; } tomcat.setPort(Integer.valueOf(webPort)); StandardContext ctx = (StandardContext) tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath()); System.out.println("configuring app with basedir: " + new File("./" + webappDirLocation).getAbsolutePath()); // Declare an alternative location for your "WEB-INF/classes" dir // Servlet 3.0 annotation will work File additionWebInfClasses = new File("target/classes"); WebResourceRoot resources = new StandardRoot(ctx); resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes", additionWebInfClasses.getAbsolutePath(), "/")); ctx.setResources(resources); tomcat.start(); tomcat.getServer().await(); } }
Add a Servlet
package servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet( name = "MyServlet", urlPatterns = {"/hello"} ) public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletOutputStream out = resp.getOutputStream(); out.write("hello heroku".getBytes()); out.flush(); out.close(); } }
Add a JSP
Create a file called index.jsp in the src/main/webapp directory:
<html> <body> <h2>Hello Heroku!</h2> </body> </html>
Run your application
On Mac and Linux, the command is:
$ mvn package
$ sh target/bin/webapp
That is all. 🙂 If you have any problem feel free to comment bellow.