Monday 5 June 2017

Create a java web application using embedded tomcat

Create a java web application using embedded tomcat


"Embedded" means that your program ships with the server within it as opposed to a web application being deployed to external server.
With embedded server your application is packaged with the server of choice and responsible for server start-up and management. You can run your web program like a regular java program. You can create war or executable jar file to execute your web program.
From the user standpoint the difference is:
  • Application with embedded server looks like a regular java program. You just launch it and that's it.
  • Regular web application is usually a war archive which needs to be deployed to some server but in this case server resides within program.

Steps to create java web application using embedded tomcat.


Create a java web application using embedded tomcat


Step 1: Create a maven project EmbeddedTomcatExample.

Step 2: Add below dependency in pom.xml.
<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>
  <groupId>com.embedtomcat</groupId>
  <artifactId>EmbeddedTomcatExample</artifactId>
  <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <tomcat.version>9.0.0.M6</tomcat.version>
    </properties>
    
    <dependencies>
        
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>         
        <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</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>
    
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>appassembler-maven-plugin</artifactId>
                <version>1.1.1</version>
                <configuration>
                    <assembleDirectory>target</assembleDirectory>
                    <programs>
                        <program>
                            <mainClass>com.embedtomcat.embedded.EmbeddedTomcatExample</mainClass>
                            <name>webapp</name>
                        </program>
                    </programs>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>assemble</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>    
    </build>
    <name>EmbeddedTomcatExample</name>
</project>

This pom.xml defines the dependencies that you’ll need to run Tomcat in an embedded mode.

The last 3 entries are only required for applications that use JSP files. If you use this technique for an application that doesn’t use JSPs then you can just include the first 3 dependencies.

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. 
Step 3: Create JSP file.

We will display content of this JSP file on browser. For example, I created index.jsp file inside webapp folder. You need to create webapp folder in parallel of java folder. 
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <title>JSP file</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <p>
            This is a simple JSP file to test EmbeddedTomcat.            
        </p>
    </body>
</html>
Step 4: Create main method.

Add a launcher class EmbeddedTomcatExample which have main method, which is responsible to add webapp in tomcat container and start tomcat server.
import java.io.File;

import javax.servlet.ServletException;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;

public class EmbeddedTomcatExample {

 public static void main(String[] args) throws LifecycleException, InterruptedException, ServletException {

  String docBase = "src/main/webapp/";

  Tomcat tomcat = new Tomcat();
  String webPort = System.getenv("PORT");
        if(webPort == null || webPort.isEmpty()) {
            webPort = "8080";
        }
        tomcat.setPort(Integer.valueOf(webPort));

  tomcat.addWebapp("/", new File(docBase).getAbsolutePath());
   System.out.println("configuring app with basedir: " + new File("./" + docBase).getAbsolutePath());

  tomcat.start();
  tomcat.getServer().await();
 }

}

Step 5: Run application.

We can run this program directly from eclipse for testing purpose or create runnable jar and execute this command (java -jar EmbeddedTomcatExample.jar) in command editor.


Create a java web application using embedded tomcat

When we choose option for program to run as Java application, below logs print on console.
Jun 05, 2017 1:11:03 PM org.apache.catalina.core.StandardContext setPath
WARNING: A context path must either be an empty string or start with a '/' and do not end with a '/'. The path [/] does not meet these criteria and has been changed to []
configuring app with basedir: C:\EmbeddedTomcat\EmbeddedTomcatExample\.\src\main\webapp
Jun 05, 2017 1:11:04 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Jun 05, 2017 1:11:04 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFO: Using a shared selector for servlet write/read
Jun 05, 2017 1:11:04 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Tomcat
Jun 05, 2017 1:11:04 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/9.0.0.M6
Jun 05, 2017 1:11:05 PM org.apache.catalina.startup.ContextConfig getDefaultWebXmlFragment
INFO: No global web.xml found
Jun 05, 2017 1:11:06 PM org.apache.jasper.servlet.TldScanner scanJars
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Jun 05, 2017 1:11:07 PM org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [449] milliseconds.
Jun 05, 2017 1:11:07 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler [http-nio-8080]

When you see this info log (INFO: Starting ProtocolHandler [http-nio-8080]) in console, you can hit below URL on browser. If your system is already use 8080 port, you can change with other port like 9090.

http://localhost:8080/

Create a java web application using embedded tomcat

This example you can download.