Monday, March 28, 2016

Create Web Application with Maven (Tomcat, WAR File)

This post is a step-by-step tutorial which shows how to create a simple Java webapp project using Maven - a popular Java build tool. The project will be packaged into a WAR file and deployed to a local Tomcat web server. The following technologies will be used:

  • Java 8 (1.8.0_66)
  • Tomcat 8 (8.0.32)
  • Apache Maven 3 (3.3.9)

This tutorial assumes that Java 8 and Apache Maven 3 have been already installed and properly configured. However, Tomcat 8 installation is discussed to a certain extent.

Generating Project Skeleton

The first thing we need to do is to create a web project from Maven template. This can be done with the following Maven command:
mvn archetype:generate -DgroupId={app-package} 
    -DartifactId={app-name} 
    -DarchetypeArtifactId=maven-archetype-webapp 
    -DinteractiveMode=false
Ok, now let's replace placeholders with some real values and generate a sample web project:
mvn archetype:generate -DgroupId=net.softwaregeek 
    -DartifactId=sample-web-app 
    -DarchetypeArtifactId=maven-archetype-webapp 
    -DinteractiveMode=false
If the command is executed successfully the following folder structure is created:
sample-web-app/
├── pom.xml
└── src
    └── main
        ├── resources
        └── webapp
            ├── WEB-INF
            │   └── web.xml
            └── index.jsp
Maven enforces a certain project structure. I won't drill down into its details here. Please visit official guide to learn more about the Maven standard directory layout.

Installing Tomcat

Tomcat installation is an easy task. This section is included for completeness. If you have already configured a Tomcat instance feel free to skip to the next part.

As mentioned previously this tutorial leverages Tomcat 8.0.32. It can be downloaded from here. For Linux/OS X users I'd suggest using tar.gz archive. For Windows users a 32-bit or 64-bit zip archive probably works best. Choose the one appropriate for your system. When archive has been downloaded, unpack it to the folder of the name you like. Basically that's all. There are several configuration options available, but I won't discuss them as they are not relevant for this tutorial.

Tomcat requires either JAVA_HOME or JRE_HOME environment variable to be set in order to work properly. If you have JDK installed use the former one and set its value to the path where JDK resides. If you have only JRE use the latter one and set its value to the path of JRE installation. I assume you know how to set environment variables in your system, so I won't describe that process.

Let's verify our Tomcat installation. Throughout this tutorial I will use name $CATALINA_HOME to reference the folder where Tomcat was installed. In order to start the web server, open terminal application, navigate to the folder $CATALINA_HOME/bin and type in the following command:
./startup.sh
Windows users should leverage *.bat files and remove the prefix which explicitly references the current directory (./). So the command looks like this:
startup.bat
From now on I will use Bourne shell files (*.sh) because my development environment is based on OS X. Windows users, just keep the difference in mind and modify commands appropriately.

Now open a browser and type in the following in the address bar:
http://localhost:8080/
If everything went well you should see Tomcat management console. Congratulations! You have Tomcat instance up and running. In order to stop it, open terminal application, navigate to the folder $CATALINA_HOME/bin and type in the following command:
./shutdown.sh

Deploying to a Local Tomcat Instance

Now it is time to build our project and deploy it to the local Tomcat web server. Open terminal application, navigate to the sample-web-app folder (or whatever you named it) and type in the following command:
mvn package
If everything went fine, you should see a bunch of output, ending with something like this:
[INFO] ----------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ----------------------------------------------------------------
[INFO] Total time: 0.905 s
[INFO] Finished at: 2016-03-22T17:14:41+02:00
[INFO] Final Memory: 12M/309M
[INFO] ----------------------------------------------------------------
Folder structure of the project now looks like the following:
sample-web-app/
├── pom.xml
├── src
│   └── main
│       ├── resources
│       └── webapp
│           ├── WEB-INF
│           │   └── web.xml
│           └── index.jsp
└── target
    ├── classes
    ├── maven-archiver
    │   └── pom.properties
    ├── sample-web-app
    │   ├── META-INF
    │   ├── WEB-INF
    │   │   ├── classes
    │   │   └── web.xml
    │   └── index.jsp
    └── sample-web-app.war
As you can see a directory named "target" is created by Maven. This is the place where Maven stores results of a build. There can be lots of files generated in the build process. The most interesting one is our web application archive (WAR file):
sample-web-app/target/sample-web-app.war
Let's take it and deploy to the previously configured local Tomcat instance. There are multiple ways to deploy a web application to the Tomcat web server. Here I will describe how to do it via web application manager. Start up your Tomcat web server, open a browser and navigate to the following page:
http://localhost:8080/
You should see a Tomcat management console:

Click "Manager App" button. An authentication pop-up window will be shown where you should type in login/password of a Tomcat administrator. If you are not sure where to get these values please read this post which explains the details.

After successful authentication Tomcat Web Application Manager should be opened:

Scroll down to the "WAR file to deploy" section and click "Choose file" button. In the appeared dialog select the WAR file which was created earlier as part of a build process. Finally click "Deploy" button. You might need to wait for a while. If everything went well you should see "sample-web-app" application listed in the "Applications" section with "Running" column value set to "true".

Now navigate to the following page to see "Hello World!" response from your application:
http://localhost:8080/sample-web-app/
Congratulations! You have "sample-web-app" application deployed to a local Tomcat web server! Now it is time to write some Java code.

Simple Servlet Example

Let's customize a little our web application by adding a simple servlet which handles GET requests and returns current date and time:
package net.softwaregeek;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

@WebServlet("/datetime")
public class DateTimeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.getWriter().println(new Date());
    }
}
Take the above code and save it in the following file:
sample-web-app/src/main/java/net/softwaregeek/DateTimeServlet.java
The code is simple enough, but let's take a brief look at it anyways. Annotation @WebServlet specifies a path to access our servlet. It is relative to the application context. In our case, application context is /sample-web-app, hence servlet will be accessible at /sample-web-app/datetime. In principal, servlets are not tied to the HTTP protocol, but HTTP servlets are the most widespread, so extending HttpServlet is a good option for DateTimeServlet class. By overriding doGet method servlet declares it will respond to GET requests. The body of the overridden method simply gets the current timestamp and returns it as the response.

In order to compile DateTimeServlet we need a dependency on Servlet API. Add the following lines to the pom.xml ("dependencies" section):
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>
Now go to sample-web-app folder and build the project as you did earlier using the following Maven command:
mvn package
When deploying the project again as was described earlier to the same Tomcat instance you might get an error similar to the following:
FAIL - War file "sample-web-app.war" already exists on server
In order to fix this the previous version of the application should be undeployed first. Find sample-web-app in the "Applications" section and click "Undeploy" button in the corresponding row:

Now deploy fresh build of the sample-web-app application and navigate to the following path in your browser:
http://localhost:8080/sample-web-app/datetime
You should see a page with text similar to the following:
Mon Mar 28 14:56:24 EEST 2016
It means sample-web-app application is up and running. Also DateTimeServlet is deployed and returns current date and time as expected.

Conclusion

In this tutorial a simple web application was generated via Maven build tool. Then a local Tomcat instance was installed and the application was built and deployed to that instance. A simple HTTP servlet which responds to GET requests and returns current timestamp was developed in order to customize the application a little. This tutorial is very basic and I hope it will encourage your further exploration!

Thank you for reading!
Andrii

3 comments:

  1. Great article. I like your blog. Thanks for sharing.

    wordpress Training in Chennai

    ReplyDelete
  2. Great. This was exactly what I was looking for. Just a simple tutorial with only maven, commandline, java and tomcat. Thanks a lot!

    ReplyDelete
    Replies
    1. Hi Patrik,
      I'm glad it was helpful for you :)

      Delete