ObjectiveOur 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
RequirementsPrivileged 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
IntroductionJava 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).
SetupSetting 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.
Tomcat serverFirst we need to install the Tomcat server itself. We add the admin webapps that can handle deployment from the web interface.
Note that we added
yum install tomcat tomcat-webapps.noarch tomcat-admin-webapps.noarch
tomcat-webappsto 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 TomcatThe 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
tomcatuser 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:
These lines must be uncommented, and a password needs to be added to the
<!-- <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>
adminuser in order to enable deployment on the web interface. The result should be something like the following:
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.
<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>
Starting the serverWe are ready to start the Tomcat server using
To start Tomcat after boot, we can also enable it, but this step is optional.
# systemctl start tomcat
# systemctl enable tomcat
Testing the settingsNow that the server is up, we'll test our settings. Direct a web browser to port
8080of 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
adminand 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:
/examplesapplication deployed - this is provided by the
tomcat-webappspackage installed earlier.
With this the Tomcat setup is completed, and we are able to access the management interface.
Setup NetbeansTo 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:
And start it:
$ chmod +x netbeans-8.2-linux.sh
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 applicationAs 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 projectWe'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 projectfrom 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/projectsis 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
webapp01that 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_HOMEenvironment variable, which is
/usr/share/tomcatby 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.
Writing codeWe'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:
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.
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>");
Building the projectAfter editing the source code, we need to build the project. This is done with the
Clean and Build Projectoption 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
adminuser'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
warfile (Web Application Archive) and pushes it trough the Tomcat Manager Application, while also preserving it on disk, on the project's
distdirectory (short for distribution).
Alternative deployment optionsWhile 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
warfile, we'll use that to deploy the application into other Tomcat instances.
Deployment by command lineThe most simple way is by command line. As Tomcat is set to autodeploy by default, any
warfile appearing in it's
webappsdirectory will be automatically deployed. We deployed our
webapp01with the IDE in the previous section, but we could simply copy it into Tomcat with the following command:
Note that this is done as
# cp /var/projects/webapp01/dist/webapp01.war /usr/share/tomcat/webapps/
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
warfile 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:
If the Tomcat instance is running on a remote machine, we can also use any file transfer methods that we can think of, including
# chown tomcat:tomcat /usr/share/tomcat/webapps/webapp01.war
To copy the file to the remote server in the name of the
scp /var/projects/webapp01/dist/webapp01.war tomcat@remote-tomcat-server:/usr/share/tomcat/webapps/
tomcatmeans file ownership will be handled on the fly.
Deployment by Tomcat Manager ApplicationWe have set up and used the
adminTomcat 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
warfile that we'll deploy:
After submitting with the
deploybutton the Manager Application will present the main page again, where our
webapp01application will be listed within the deployed application list.
Verification of successful deploymentAside 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
8080, the name of our application (
webapp01), and the servlet's name, which is
ConclusionIn 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.