Our objective is to develop a simple Java Servlet application using Netbeans IDE, and deploy it into a Tomcat application container using command line and the manager application.
Operating System and Software Versions
- Operating system: any recent Linux distribution
- Software: Apache Tomcat 8, Netbeans 8.2
Privileged access to the system
- # – requires given linux commands to be executed with root privileges either directly as a root user or by use of
- $ – given linux commands to be executed as a regular non-privileged user
Java based applications running in application containers are one of the most common application setups now-days. Java is a robust, platform-independent, high-level programming language. An application container, like Tomcat or WildFly (formerly JBoss) is able to provide a standard context for the applications deployed in it, making common tasks like logging easy to implement, also handling the server role (listening to incoming requests from clients), adding capabilities like clustering, and enable sharing or sandboxing of resources within the container. These features let developers focus on processing the requests and providing the responses, as they don’t need to develop yet another server application for each service.
In this guide we will develop a trivial Java Servlet using the Netbeans IDE 8.2, and deploy it into a Apache Tomcat container 8.5, so the servlet’s services are reachable on the network. We use a Fedora 28 desktop as the lab machine for both running the Tomcat server and used as a development environment, but note that you could write the servlet in a text editor, and build it on dedicated build servers, and also use any recent Tomcat to deploy your application, possibly far from the developer machine. While Netbeans can handle the deployment to it’s full length, we’ll cover the case when development tools have no direct access to the servers (which should be the case in production).
Tomcat is so common it is shipped with any major distribution’s base repositories (and also available in a tar.gz), and the platform-independent nature of Java makes it easy to deploy application containers to nearly anywhere – hence it’s popularity. If the developer does not use platform-dependent packages, his/her application will run anywhere the same way. The most common problems came from Java versions (for example, you do not want to deploy an application developed in Java 1.8 on a server running Java 1.6), or missing packages (a custom Java package used in the application, but not included in the distributed package), but these should come out in the early phases of development.
Setting up the lab environment is pretty straightforward. We’ll install and setup the Tomcat server and integrate the IDE with it, both running on the same JVM (Java Virtual Machine), and deployment made automatic. This ensures that there will be no Java version issues, and makes testing easy and fast. The Tomcat server will only listen on localhost using default ports and management applications shipped with the distribution.
First we need to install the Tomcat server itself. We add the admin webapps that can handle deployment from the web interface.
yum install tomcat tomcat-webapps.noarch tomcat-admin-webapps.noarch
Note that we added
tomcat-webapps to the installation. These will not be needed in this tutorial, but are good example applications with source code for further getting used to servlets, JSP (JavaServer Pages), etc.
Setting up administrative users in Tomcat
The default installation leave the installed admin applications closed. To open them we have to add passwords to the users within Tomcat. We could add custom users and roles, or integrate the server with some central identity management like an LDAP server, but that’s beyond the scope of this tutorial. We’ll simply use the default roles shipped with the installation.
On RHEL flavors the configuration file we need to adjust is on the following path:
The XML file can’t be edited by a user with normal privileges. You need to work with the
tomcat user added automatically by the installation, or
It is a long file, but we need to modify only the end of it.
You’ll see the following lines, all commented out:
<!-- <role rolename="admin"/> --> <!-- <role rolename="admin-gui"/> --> <!-- <role rolename="admin-script"/> --> <!-- <role rolename="manager"/> --> <!-- <role rolename="manager-gui"/> --> <!-- <role rolename="manager-script"/> --> <!-- <role rolename="manager-jmx"/> --> <!-- <role rolename="manager-status"/> --> <!-- <user name="admin" password="<must-be-changed>" roles="admin,manager,admin-gui,admin-script,manager-gui,manager-script,manager-jmx,manager-status" /> --> </tomcat-users>
These lines must be uncommented, and a password needs to be added to the
admin user in order to enable deployment on the web interface. The result should be something like the following:
<role rolename="admin"/> <role rolename="admin-gui"/> <role rolename="admin-script"/> <role rolename="manager"/> <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <user name="admin" password="SecretPassword" roles="admin,manager,admin-gui,admin-script,manager-gui,manager-script,manager-jmx,manager-status" /> </tomcat-users>
For the lab environment we don’t need a strong password, but aside testing, always use strong passwords. After adding the above changes, save the file.
Starting the server
We are ready to start the Tomcat server using
# systemctl start tomcat
To start Tomcat after boot, we can also enable it, but this step is optional.
# systemctl enable tomcat
Testing the settings
Now that the server is up, we’ll test our settings. Direct a web browser to port
8080 of the machine, and click on the “manager app” to the upper right of the page provided by Tomcat. A popup window should appear, asking for credentials for the Tomcat Manager Application. Provide the username
admin and the password that was set for it in the previous section:
If our setup is right, and we provide the right credentials, we should see a colorful page, and on top of it the list of deployed applications, provided by the Manager Application, similar to the screenshot below:
/examples application deployed – this is provided by the
tomcat-webapps package installed earlier.
With this the Tomcat setup is completed, and we are able to access the management interface.
To have an environment for development, we’ll install Netbeans IDE (Integrated Development Environment). We could use any other, or even a simple text editor. The Netbeans IDE can be downloaded from the Netbeans home page. After downloading the installer, we need to add execute right to the installer script:
$ chmod +x netbeans-8.2-linux.sh
And start it:
A graphical wizard will pop up, and will guide trough the installation process. After successful installation a Netbeans icon appears on the desktop. Clicking on it will start the IDE.
Developing the sample application
As this tutorial is not about core development, we’ll use wizards provided by the IDE to create the sample application we plan to deploy into Tomcat.
Creating web project
We’ll create a web project within Netbeans. This process will ensure our project is ready to be deployed into a Tomcat container with minimal effort. To do so, start the IDE, and select
File -> New project from the menu, then choose
Java Web -> Web Application:
We need to name the project, and select path for it in the filesystem. Note that on the screenshot below, a non-default path
/var/projects is selected. This directory is created by hand, and given to the operating system user running the IDE. The default path is within the home directory of the user running the IDE, so by default filesystem rights will not be an issue while working on the project. If you need to put your projects some other place, you need to ensure you can write to that specific location.
The project’s name can be fairly anything, but as we go mostly with the defaults, we use
webapp01 that will be part of the URL where the application is reachable.
On the next screen we need to specify the target server, Java version and context path. We choose
Apache Tomcat or TomEE, and leave the other options on defaults.
We need to provide the path to the Tomcat server, namely the
CATALINA_HOME environment variable, which is
/usr/share/tomcat by default on RHEL flavors.
We can see that our new project is not quite empty, the IDE generated a default content on project creation. We add a new package to the source packages that will override the default package:
We need to name the package. Notice that the new package will be created on the path of the project:
Next we add a new servlet to our project, and place it into the new package we created:
We need to name the servlet. It’s source code will be placed into the package (which is a directory at this stage of development) on the project path.
The name we choose for the servlet here is
systeminfo, as it will provide with some information about the software environment it is running on. This name will be also part of the URL, namely the endpoint where the service is reachable.
We’ll see that our new servlet is pre-populated already with sample code. We’ll keep most of it, we’ll replace the lines highlighted:
Using the source code editor of the IDE, we overwrite the lines highlighted with the following:
out.println("<title>System Information</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Servlet systemInfo at " + request.getContextPath() + "</h1>"); out.println("<table border=\"1\">"); out.println("<tr><td>Operating system name:</td><td>" + System.getProperty("os.name") + "</td></tr>"); out.println("<tr><td>Operating system version:</td><td>" + System.getProperty("os.version") + "</td></tr>"); out.println("<tr><td<Java vendor:</td><td>" + System.getProperty("java.vendor") + "</td></tr>"); out.println("<tr><td>Java version:</td><td>" + System.getProperty("java.version") + "</td></tr>"); out.println("</table>");
The code above will read some system properties from the operating system, and present them in a HTML page. While this application is very basic, the deployment process is the same for large, real world applications as well.
Building the project
After editing the source code, we need to build the project. This is done with the
Clean and Build Project option that can be found under the
As our Tomcat server is equipped with the manager application, the IDE will initialize the deployment automatically. For that it will ask for the username and password for the Tomcat user who can deploy applications within the container. We’ll provide the
admin user’s credentials we set up while configuring the Tomcat server.
If all is set up properly, our application will successfully build and the IDE will deploy it into Tomcat. The report of the build will be displayed in the output box of the IDE on completion.
With this step our application is deployed into Tomcat and ready to serve incoming requests. The IDE’s build function provides a
war file (Web Application Archive) and pushes it trough the Tomcat Manager Application, while also preserving it on disk, on the project’s
dist directory (short for distribution).
Alternative deployment options
While the automatic deployment is a nice feature, deploying to production should not be done this way. The production servers should be out of the reach of development tools, and fairly anything else that does not needed for their services. As the IDE generated a distributable
war file, we’ll use that to deploy the application into other Tomcat instances.
Deployment by command line
The most simple way is by command line. As Tomcat is set to autodeploy by default, any
war file appearing in it’s
webapps directory will be automatically deployed. We deployed our
webapp01 with the IDE in the previous section, but we could simply copy it into Tomcat with the following command:
# cp /var/projects/webapp01/dist/webapp01.war /usr/share/tomcat/webapps/
Note that this is done as
root, who has the right to write into Tomcat’s directories. Keep in mind that this command alone will leave a possible error, as the
war file is owned by
root, and while Tomcat can read it, it can not delete it, hence undeployment of the application will fail.
To solve this we need to set the ownership of the file to the operating system user that runs Tomcat server:
# chown tomcat:tomcat /usr/share/tomcat/webapps/webapp01.war
If the Tomcat instance is running on a remote machine, we can also use any file transfer methods that we can think of, including
scp /var/projects/webapp01/dist/webapp01.war tomcat@remote-tomcat-server:/usr/share/tomcat/webapps/
To copy the file to the remote server in the name of the
tomcat means file ownership will be handled on the fly.
Deployment by Tomcat Manager Application
We have set up and used the
admin Tomcat user in the previous sections. We can use it to deploy our application trough the web interface. On the manager’s main page, below the list of deployed applications is the form that can be used to upload an application for deployment:
We need to browse the
war file that we’ll deploy:
After submitting with the
deploy button the Manager Application will present the main page again, where our
webapp01 application will be listed within the deployed application list.
Verification of successful deployment
Aside the verification trough the Manager Application, we can see the process and result of the deployment in the Tomcat server logs:
# tail -f /var/log/tomcat/catalina.2018-10-13.log 13-Oct-2018 07:49:29.291 INFO [http-nio-8080-exec-16] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/var/lib/tomcat/webapps/webapp01.war] 13-Oct-2018 07:49:29.423 INFO [http-nio-8080-exec-16] org.apache.jasper.servlet.TldScanner.scanJars 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. 13-Oct-2018 07:49:29.426 INFO [http-nio-8080-exec-16] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/var/lib/tomcat/webapps/webapp01.war] has finished in  ms
And we can access our new service with the URL built from the server’s name (localhost in this case), the serving port
8080, the name of our application (
webapp01), and the servlet’s name, which is
In this tutorial we successfully developed, built and deployed an example application using Netbeans and Tomcat. We used features of the IDE so we didn’t have to write and pack every aspect of a web application, by simply selecting the target server of deployment we where provided with all the metadata needed by Tomcat to successfully deploy our application.
We relied on Tomcat’s server functionality to make our application reachable from a browser trough HTTP protocol we didn’t needed to implement. With such tools we can focus on building the business logic, rather than implementing infrastructural functions already presented to us by the container.