1. Home
  2. Tutorials
  3. Java
  4. Tomcat
Yolinux.com Tutorial

 

Tomcat: Java Servlets, JSP, Apache-Tomcat, a Database (PostgreSQL or MySQL), Apache httpd and Linux

This tutorial covers the use of Apache Tomcat, Java and Linux

This covers dynamic content using Java servlets, Java Server Pages (JSP page compiler), Apache-Tomcat, Apache httpd web server and a Database (PostgreSQL or MySQL) on Linux. A configuration presented here will allow one to make a web request to the Apache web server which will recognize it as request for a servlet to be handled by Tomcat. Tomcat, the Java Servlet and JSP engine, will execute the Java Servlet which will use JDBC to access a database (PostgreSQL or MySQL). The servlet will dynamically generate a web page based on the results of the database query and will provide these results to Apache httpd which will deliver the web content back to the requesting browser.

Instead of using C/C++ or PERL for a CGI back-end web server process, one may use Java servlets processed by the Apache project's "Tomcat". The Apache httpd web server will be configured to interface with Tomcat and it's JVM (Java virtual machine). Servlet programs are written as Java classes which inherit from "HttpServlet" to provide much of their principal function.

Java Server Pages (JSP) will utilize Tomcat's page compiler to generate dynamic web pages based on custom tags in one's HTML pages which are processed and served. These pages use the tag "<% %>" to denote JSP directives to be dynamically processed.

This tutorial applies to Apache Tomcat 6 and later. Older releases of Tomcat (version 4) are configured differently.

An example of a Java Servlet using JDBC to access a database (PostgreSQL or MySQL) is also covered.

Contents:

Java Installation/Configuration:

In order to write and compile a Java programs, applets or servlets one must download the Java Development Kit (JDK) which provides a compiler, class libraries and tools to compile and run Java code. In this tutorial we will use the Oracle/Sun JDK but I'm sure any will do. See YoLinux Java for a list of available JDK's for Linux. Linux also ships with OpenJDK which will also work with Tomcat.

One must choose complimentary versions of Tomcat and Java as they must match appropriately:

Apache Tomcat VersionServlet SpecJSP SpecEL SpecWebsocket SpecJASPIC SpecSupported Java Versions
94.02.33.01.11.18+
83.12.33.01.11.1 (Tomcat 8.5)7+
73.02.22.21.1N/A6+ (7+ for WebSocket support)
62.52.12.1N/AN/A5+
Where:
  • EL is the "Unified Expression Language" used for embedding expressions into JSP web pages and based on JSTL to employ XML based scripting.
  • JASPIC provides an interface to authentication implementations with Tomcat

Oracle JDK:

Note:
  • The Java Runtime Environment (JRE) will be adequate to configure the server environment but the Software Development Kit (SDK) is required if one wants to write and compile Java programs. The Java SDK is available in RPM and tar format.
  • Tomcat version require compatible Java versions. Thus use Java version 1.8 or 1.7 for use with Tomcat version 8, use Java 1.7 for use with Tomcat 7 and Java 1.6 for use with Tomcat 6.

Download: RHEL:
  • Java JDK 1.8: jdk-8u77-linux-x64.rpm (Red Hat, Fedora, CentOS or Suse systems) or jdk-8u77-linux-x64.tar.gz (all other versions of Linux).
  • Java JDK 1.7: jdk-7u40-linux-x64.rpm

RHEL Install: rpm -ivh jdk-8u77-linux-x64.rpm

SDK installed in /usr/java/latest/.

Configuration:

Set the environment variable PATH. Add statement to $HOME/.bash_profile or $HOME/.bashrc or shell script which controls the environment.
#!/bin/bash
if [ -d /usr/java/latest ]
then
    export PATH=/usr/java/latest/bin:$PATH
    export JAVA_HOME=/usr/java/latest
    export CLASSPATH=/usr/java/latest/lib/tools.jar:/usr/java/latest/jre/lib/rt.jar
    export MANPATH=$JAVA_HOME/man:/opt/man:$MANPATH
fi
The shell script may be re-executed with the command: . .bashrc

Test:

Use the following test program: Test.java
1public class Test
2{
3   public static void main(String[] args)
4   {
5      System.out.println("Hello world");
6   }
7}

Compile: javac Test.java
Note that the file name and the class name must be the same. The result of the compile is the file: Test.class

Run:

[prompt]$ java Test
Hello world

Open JDK:

OpenJDK can be installed using package management:

  • RHEL/CentOS/Fedora:
    • Java 1.7: yum install java-1.7.0-openjdk java-1.7.0-openjdk-devel java-1.7.0-openjdk-javadoc alternatives
    • Java 1.6: yum install java-1.6.0-openjdk java-1.6.0-openjdk-devel java-1.6.0-openjdk-javadoc alternatives
      (Note: JAVA_HOME=/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/)
  • Ubuntu: (Ubuntu 12.4: add repository: add-apt-repository ppa:openjdk-r/ppa, not required for 16.04+)
    • Java 1.9: apt-get install openjdk-9-jdk
    • Java 1.8: apt-get install openjdk-8-jdk
    • Java 1.7: apt-get install openjdk-7-jdk
    • Java 1.6: apt-get install openjdk-6-jdk
    To support multiple versions, select a default: update-alternatives --config java
    (Note: JAVA_HOME=/usr/lib/jvm/java-7-openjdk/)


Links:

Apache Project - Tomcat:

Tomcat is the Java "container" or processor for Java Servlets and Java Server Pages (JSP). Note also that Java must be installed in order for Tomcat to operate. (See previous section above) This tutorial will focus on the use of Tomcat with Apache but it should be noted that the default Tomcat installation enables Tomcat to be a stand-alone http web server and servlet container.

Tomcat can be directly downloaded from the Apache Tomcat website or installed by the package manager from the package repository. By default RHEL6 comes with Tomcat 6.0.

Apache Tomcat Java Servlet and JSP container home page

Tomcat 8/9:

Tomcat 9 requires Java 1.8. Tomcat 8 requires Java 1.7 or 1.8 JDK installation. Tomcat 8 will NOT run with Java version 1.6!

Ubuntu 18.04 users have the option of installing using the package manager: sudo apt-get install tomcat9

Ubuntu 16.06 users have the option of installing using the package manager: sudo apt-get install tomcat8

All versions of Linux can install using the tar file available from the Apache Tomcat website.

Download: apache-tomcat-8.0.0-RC1.tar.gz

Install:
  • cd /opt
  • tar xzf ~/Downloads/apache-tomcat-8.0.0-RC1.tar.gz
    (Result: /opt/apache-tomcat-8.0.0-RC1/)
Start: /opt/apache-tomcat-8.0.30/bin/startup.sh

Stop: /opt/apache-tomcat-8.0.30/bin/shutdown.sh

Build jsvc: Jsvc allows the application (e.g. Tomcat) to perform some privileged operations as root (e.g. bind to a port < 1024), and then switch identity to a non-privileged user.
Build jsvc daemon project (C source) - included with tomcat binary distribution
  • cd /opt/apache-tomcat-8.0.0-RC1/bin
  • tar xzf commons-daemon-native.tar.gz
  • cd commons-daemon-1.0.15-native-src/unix
  • ./configure --with-java=/usr/java/latest
  • make
  • cp jsvc ../..
  • cd ../..
Script to start Tomcat 8.0: /opt/bin/tomcat8start.sh
#!/bin/bash
if [ -d /usr/java/latest ]
then
  export PATH=/usr/java/latest/bin:$PATH
  export JAVA_HOME=/usr/java/latest
  export CLASSPATH=/usr/java/latest/lib/tools.jar:./
  export MANPATH=$JAVA_HOME/man:/opt/man:$MANPATH
fi

export CATALINA_HOME=/opt/apache-tomcat-8.0.0-RC1/
    CATALINA_BASE=$CATALINA_HOME
    cd $CATALINA_HOME
    ./bin/jsvc \
        -classpath $CATALINA_HOME/bin/bootstrap.jar:$CATALINA_HOME/bin/tomcat-juli.jar \
        -outfile $CATALINA_BASE/logs/catalina.out \
        -errfile $CATALINA_BASE/logs/catalina.err \
        -Dcatalina.home=$CATALINA_HOME \
        -Dcatalina.base=$CATALINA_BASE \
        -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
        -Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties \
        org.apache.catalina.startup.Bootstrap
Make the script executable: chmod +x /opt/bin/tomcat8start.sh

Example start:
[root@hostname apache-tomcat-8.0.0-RC1]# /opt/bin/tomcat8start.sh
Using CATALINA_BASE:   /opt/apache-tomcat-8.0.0-RC1/
Using CATALINA_HOME:   /opt/apache-tomcat-8.0.0-RC1/
Using CATALINA_TMPDIR: /opt/apache-tomcat-8.0.0-RC1//temp
Using JRE_HOME:        /usr/java/latest
Using CLASSPATH:
/opt/apache-tomcat-8.0.0-RC1//bin/bootstrap.jar:/opt/apache-tomcat-8.0.0-RC1//bin/tomcat-juli.jar

See all jsvc daemon options with "jsvc --help"

Pitfall: If you get a ClassNotFoundException or a NoClassDefFoundError for a Commons-Daemon class, add the Commons-Daemon JAR to your classpath or use -cp argument when launching jsvc.

Run:

Place WAR file applications in /opt/apache-tomcat-8.0.0-RC1/webapps/ and access via the URL http://localhost:8080/

Try the example applications in /opt/apache-tomcat-8.0.0-RC1/webapps/examples/ and access via the URL http://localhost:8080/examples/

If executing a single Java class file like the HelloWorld example below, place in the directory /opt/apache-tomcat-8.0.0-RC1/webapps/ROOT/WEB-INF/classes/ and access via the URL http://localhost:8080/HelloWorld

Tomcat Configuration:

File: /opt/apache-tomcat-8.0.0-RC1/conf/tomcat-users.xml
1<tomcat-users>
2  <role rolename="tomcat"/>
3  <role rolename="role1"/>
4  <user username="tomcat" password="tomcat" roles="tomcat"/>
5  <user username="both" password="tomcat" roles="tomcat,role1"/>
6  <user username="role1" password="tomcat" roles="role1"/>
7</tomcat-users>

Tomcat 6:

This installation uses Tomcat RPM packages furnished with RHEL6.

Install:
  • tomcat6-6.0.24-45.el6.noarch
  • tomcat6-lib-6.0.24-45.el6.noarch
  • tomcat6-el-2.1-api-6.0.24-45.el6.noarch
  • tomcat6-servlet-2.5-api-6.0.24-45.el6.noarch
  • tomcat6-jsp-2.1-api-6.0.24-45.el6.noarch
  • apache-tomcat-apis-0.1-1.el6.noarch
  • jakarta-commons-pool-tomcat5-1.3-12.7.el6.x86_64
  • jakarta-commons-dbcp-tomcat5-1.2.1-13.8.el6.noarch
This installation uses the OpenJDK 1.6.0 RPM packages.

Documentation:

Config files:

FileDescription
/etc/sysconfig/tomcat6 System configuration and file paths. Uncomment environment variable definitions
/etc/tomcat6/catalina.policy Java security permissions and access: JDBC, sockets
/etc/tomcat6/catalina.properties Java packages and settings
/etc/tomcat6/context.xml reference to WEB-INF/web.xml as a monitored resource
/etc/tomcat6/log4j.properties log4j debug levels and log file ref
/etc/tomcat6/logging.properties log file settings and log levels
/etc/tomcat6/server.xml Servlet container configuration: server properties, port numbers for services, DB connectors (MySQL, PostgreSQL, Oracle, ODBC, etc):
8080 - http (redirect 8443)
8009 - AJP/1.3 (redirect 8443)
8005 - shutdown
/etc/tomcat6/tomcat6.conf prime config file: self aware directories, user id, ..
/etc/tomcat6/tomcat-users.xml Tomcat web management console: login/passwords, roles
<?xml version='1.0' encoding='utf-8'?>
 <tomcat-users>
 <role rolename="manager"/>
 <user name="tomcat" password="supersecret" roles="manager" />
 </tomcat-users>
                                                
/etc/tomcat6/web.xml Web apps, servlets, jsp, server mime types
Preparation:
  • cd /var/lib/tomcat6/webapps/
  • mkdir -p WEB-INF/classes
  • mkdir WEB-INF/lib
Put servlets in WEB-INF/classes/ and WAR files in /var/lib/tomcat6/webapps/ and they will explode to the above layout.

Start service: service tomcat6 start (or: /etc/init.d/tomcat6 start)

Notes:
  • Tomcat will execute as user tomcat
  • To add to init boot process: /sbin/chkconfig --add tomcat6
  • Tomcat Log files: /var/tomcat6/logs/
  • JAR files and JDBC drivers: /var/tomcat6/webapps/examples/WEB-INF/lib/

Tomcat Manager:

1<tomcat-users>
2<user name="tomcat" password="tomcat" roles="tomcat" />
3<user name="role1"  password="tomcat" roles="role1"  />
4<user name="both"   password="tomcat" roles="tomcat,role1" />
5<user name="admin1" password="supersecret" roles="standard,manager,tomcat,role1" />   <!-- Added this line with "manager role" -->
6<user name="admin2" password="supersecret2" roles="admin,manager,provider" />
7</tomcat-users>
Restart after changes: service tomcat6 restart

Use URL to list web applications: http://localhost:8080/manager/list

Documentation: http://localhost:8080/tomcat-docs/manager-howto.html - [Web]

Java Servlet Example:

Hello World Tomcat servlet example WAR file:

Directory set-up:
  • mkdir -p src/main/java/com/megacorp/projectx
  • mkdir -p src/main/webapp/WEB-INF

File: src/main/java/com/megacorp/projectx/HelloWorld.java

01package com.megacorp.projectx;
02 
03import java.io.*;
04import java.text.*;
05import java.util.*;
06import javax.servlet.*;
07import javax.servlet.http.*;
08 
09public class HelloWorld extends HttpServlet {
10 
11    public void doGet(HttpServletRequest request,
12                      HttpServletResponse response)
13    throws IOException, ServletException
14    {
15        response.setContentType("text/html");
16        PrintWriter out = response.getWriter();
17        out.println("<html>");
18        out.println("<head>");
19        out.println("<title>Hello World!</title>");
20        out.println("</head>");
21        out.println("<body>");
22        out.println("<h1>Hello World!</h1>");
23        out.println("</body>");
24        out.println("</html>");
25    }
26}

Compile:
[prompt]$ javac -cp /opt/apache-tomcat-8.0.30/lib/servlet-api.jar HelloWorld.java
This generates HelloWorld.class

Relocate class file to:
  • RHEL6: /var/lib/tomcat6/webapps/examples/WEB-INF/classes/com/megacorp/projectx/HelloWorld.class
  • Tomcat 8: /opt/apache-tomcat-8.0.30/webapps/examples/WEB-INF/classes/com/megacorp/projectx/HelloWorld.class

Servlet Configuration file web.xml:
  • RHEL6: /var/lib/tomcat6/webapps/examples/WEB-INF/web.xml
  • Tomcat 8: /opt/apache-tomcat-8.0.30/webapps/examples/WEB-INF/web.xml
Edit and add the following to src/main/webapp/WEB-INF/web.xml
01<?xml version="1.0" encoding="UTF-8"?>
03         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
04         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
05                             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
06         version="3.1"
07         metadata-complete="true">
08 
09    <description>Hello World</description>
10    <display-name>Hello World</display-name>
11 
12    <servlet>
13        <servlet-name>HelloWorld</servlet-name>
14        <servlet-class>com.megacorp.projectx.HelloWorld</servlet-class>
15    </servlet>
16 
17    <servlet-mapping>
18        <servlet-name>HelloWorld</servlet-name>
19        <url-pattern>/HelloWorld</url-pattern>
20    </servlet-mapping>
21</web-app>

Note:

  • Java class com.mycompany.mypackage.MyServlet would be stored in /WEB-INF/classes/com/mycompany/mypackage/MyServlet.class
  • Libraries (JAR files, JDBC drivers, etc) held in /WEB-INF/lib/ if one follows standard configuration.

Tomcat Test: http://localhost:8080/examples/servlets/servlet/HelloWorld
Don't expect a lot. It just generates a web page dynamically which states "Hello World".

Note:

  • The mapping of path /var/tomcat6/webapps/examples/WEB-INF/classes/ to the URL /examples/servlet/ is defined in /var/tomcat6/conf/web.xml. Look for the XML tag "<servlet-mapping>".
  • Many examples with source code are included with Tomcat. See: http://localhost:8080/examples/servlets/index.html

Java Servlet WAR File Example:

Typically Java web applications are deployed as a single deployable file known as a "WAR" file (Web ARchive). Java web applications typically are comprised of multiple servlet classes, HTML and JSP pages with accompanying images and libraries. All of these can be deployed as a single Java WAR file. We will use Apache ANT and Apache Maven to build and deploy a WAR file for the HelloWorld servlet web application.

The following directory structure will be used to buld myservlet.war:
build.xml
src/main/java/com/megacorp/projectx/HelloWorld.java
src/main/webapp/WEB-INF/web.xml
src/main/webapp/index.html
Where:
  • WebApp/build.xml: This is the Apache ANT build script
  • WebApp/src/main/java/com/megacorp/projectx/HelloWorld.java: The source code to generate WEB-INF/classes/com/megacorp/projectx/HelloWorld.class, the executable Java byte code
  • WebApp/src/main/webapp/index.html: The default home page of the web application

File: WebApp/src/main/webapp/index.html
1<html>
2<head>
3<title>My App</title>
4</head>
5<body>
6<h2>My App</h2>
7<a href="HelloWorld">Execute HelloWorld servlet</a>
8</body>
9</html>

File: WebApp/src/main/webapp/WEB-INF/web.xml
01<?xml version="1.0" encoding="ISO-8859-1"?>
04  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
05                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
06  version="3.1"
07  metadata-complete="true">
08 
09    <description>Servlet Example</description>
10    <display-name>Servlet Example</display-name>
11 
12    <servlet>
13        <servlet-name>HelloWorld</servlet-name>
14        <servlet-class>com.megacorp.projectx.HelloWorld</servlet-class>
15    </servlet>
16 
17    <servlet-mapping>
18        <servlet-name>HelloWorld</servlet-name>
19        <url-pattern>/HelloWorld</url-pattern>
20    </servlet-mapping>
21 
22    <welcome-file-list>
23        <welcome-file>index.html</welcome-file>
24    </welcome-file-list>
25 
26</web-app>

Build and deply the web application:
  • Apache ANT: ant install
    see build.xml below.
  • Apache Maven: mvn install
    see pom.xml below.

This will generate the Java WAR file myservlet.war which when deployed to the Apache TomCat webapp deployment directory $TOMCAT_HOME/webapp/ will be deployed as the Java web application http://localhost:8080/myservlet/

Note that the name of the WAR file becomes a distinguishing path in the URL. Select the hyperlink on the page to execute the servlet.

For more on building a Java Web Archive (WAR) file and examples see the Java WAR files tutorial.

Build with Ant:

Build and deply the web application: ant install

File: WebApp/build.xml
01<?xml version="1.0" encoding="UTF-8"?>
02<project name="Servlet" default="all" basedir=".">
03    <description>Builds a Servlet.</description>
04    <property name="home.dir" value="./"/>
05    <property name="servlets.src.dir" location="${home.dir}/src/main/java"/>
06    <property name="app.dir" value="${home.dir}/src/main/webapp"/>
07    <property name="install.dir" value="/opt/apache-tomcat-9.0.30/webapps"/>
08    <property name="lib.dir" value="/opt/apache-tomcat-9.0.30/lib"/>
09 
10    <!-- Classpath to find servlet and java packages -->
11    <path id="classpath.base">
12      <fileset dir="${lib.dir}">
13        <include name="**/*.jar" />
14      </fileset>
15    </path>
16 
17    <target name="usage">
18       <echo message="Available targets are:"/>
19       <echo message="clean            - Remove war and class files."/>
20       <echo message="war              - Generate war file to deploy to Tomcat."/>
21       <echo message="install          - Copy war file to Tomcat war file deployment directory."/>
22    </target>
23 
24    <target name="clean" description="Remove .class and .jar files">
25       <delete includeEmptyDirs="true" failonerror="false">
26          <fileset dir="${app.dir}/WEB-INF/classes">
27             <include name="**/*.class"/>
28          </fileset>
29          <fileset dir="${home.dir}">
30             <include name="myservlet.war"/>
31          </fileset>
32       </delete>
33    </target>
34 
35    <target name="compile">
36      <mkdir dir="${app.dir}/WEB-INF/classes"/>
37      <javac srcdir="${servlets.src.dir}" destdir="${app.dir}/WEB-INF/classes" debug="true" includeAntRuntime="false">
38          <classpath refid="classpath.base"/>
39          <include name="**/*.java"/>
40      </javac>
41    </target>
42 
43    <target name="war" depends="compile">
44       <war destfile="target/myservlet.war" webxml="${app.dir}/WEB-INF/web.xml">
45          <fileset dir="${app.dir}">
46             <include name="**/*.jsp"/>
47             <include name="**/*.css"/>
48             <include name="**/*.png"/>
49             <include name="**/*.html"/>
50             <include name="WEB-INF/classes/**/*.class"/>
51          </fileset>
52       </war>
53    </target>
54 
55    <target name="install" depends="war" description="Deploy application as a WAR file">
56       <copy todir="${install.dir}" preservelastmodified="true">
57          <fileset dir="./target">
58             <include name="*.war"/>
59          </fileset>
60       </copy>
61    </target>
62 
63    <target name="all" depends="war" />
64 
65</project>
Build with Maven:

Build and install: mvn install

File: WebApp/pom.xml
03  <modelVersion>4.0.0</modelVersion>
04  <groupId>com.megacorp.projectx</groupId>
05  <artifactId>ProjectX</artifactId>
06  <packaging>war</packaging>
07  <version>1.0-SNAPSHOT</version>
08  <name>projectx</name>
10 
11  <properties>
12    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13  </properties>
14 
15  <dependencies>
16    <dependency>
17      <groupId>javax.servlet</groupId>
18      <artifactId>javax.servlet-api</artifactId>
19      <version>3.1.0</version>
20      <scope>provided</scope>
21    </dependency>
22  </dependencies>
23 
24  <build>
25    <plugins>
26      <plugin>
27        <groupId>org.apache.maven.plugins</groupId>
28        <artifactId>maven-war-plugin</artifactId>
29        <version>3.2.3</version>
30        <configuration>
31          <warSourceDirectory>src/main/webapp</warSourceDirectory>
32          <webappDirectory>/opt/apache-tomcat-9.0.30/webapps/myservlet/</webappDirectory>
33        </configuration>
34      </plugin>
35      <plugin>
36        <groupId>org.apache.maven.plugins</groupId>
37        <artifactId>maven-compile-plugin</artifactId>
38        <version>3.1</version>
39        <configuration>
40          <source>1.8</source>
41          <target>1.8</target>
42        </configuration>
43      </plugin>
44    </plugins>
45  </build>
46</project>

For more on Apache Maven, see the Yolinux Apache Maven tutorial.

Apache httpd web server proxy and Tomcat Configuration:

Apache httpd is a fast and configurable web server whic can act as a proxy front-end on port 80 to Tomcat dynamic content. This section covers using Apache httpd as the primary web server but using Tomcat to process JSP and Servlets using AJP. Connect to Apache httpd 2.4 and 2.2 with mod_proxy_ajp (comes with the httpd Linux package installations:

  • Red Hat/CentOS: /usr/lib64/httpd/modules/mod_proxy_ajp.so
  • Ubuntu: /etc/apache2/mods-available/proxy_ajp.load
Proxy a specific path other than root path. This is required if web server is still going to server static content and other non-Tomcat content.

Use AJP: /opt/apache-tomcat-9.0.30/conf/server.xml or if installed as a package /etc/tomcat/server.xml
...
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
...

Proxy Tomcat through the Apache web server:
  • Red Hat/CentOS: /etc/httpd/conf.d/tomcat-proxy.conf
    01# this line already exists by default
    02LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
    03 
    04<Proxy *>
    05 Header set Access-Control-Allow-Origin "*"
    06 AddDefaultCharset Off
    07 Order deny,allow
    08 Allow from all
    09</Proxy>
    10 
    11# This proy's everything from "/" (don't do this if you want to serve static content from the root path of the web server along side dynamic content via /apps).
    12#ProxyPass / ajp://localhost:8009/
    13#ProxyPassReverse / ajp://localhost:8009/
    14 
    15# Proxy a non-root path. This proy's everything from "/apps".
    16ProxyPass /apps ajp://localhost:8009/apps
    17ProxyPassReverse /apps ajp://localhost:8009/apps
  • Ubuntu:
    Enable Apache proxy: a2enmod proxy_ajp
    add to /etc/apache2/apache2.conf
Restart Apache:
  • Red Hat/CentOS: service httpd restart
  • Ubuntu: systemctl restart apache2

This adds "/apps/" to the URL path.

Servlet WAR file URL path configuration file WEB-INF/web.xml does not change.

Run:

  • Start Tomcat first: service tomcat start
  • Start Apache: service httpd start
    After Apache has started, one may perform a syntax check of the Apache configuration files with the following command:
    [root prompt]# /usr/sbin/apachectl configtest
    If sucessful it should return the statement: Syntax OK
  • Test with the URL:

Log Files:

  • Apache:
    • /var/log/httpd/access_log
    • /var/log/httpd/error_log
  • Tomcat: /var/tomcat6/logs/...

The Database:

We will cover connectivity to two databases:

  1. PostgreSQL
  2. MySQL
Note: If connecting to Oracle, use the JDBC driver: oracle.jdbc.driver.OracleDriver

1) PostgreSQL:

Install and configure a database. See: YoLinux Tutorial: PostgreSQL and Linux

JDBC and PostgreSQL JAR files: The "CLASSPATH" variable can set the Java runtime environment so that it will find the appropriate Java libraries (JAR files). Environment variables for Tomcat can be set in /etc/tomcat6/conf/tomcat6.conf. One may also set the CLASSPATH variable to include PostgreSQL JDBC JAR files. I did not set the CLASSPATH environment variable in the configuration file but instead employed the default path by performing the following steps:

List of PostgreSQL JDBC drivers:

[prompt]# rpm -ql postgresql-jdbc-7.1.3-2
/usr/share/pgsql/jdbc7.0-1.1.jar
/usr/share/pgsql/jdbc7.1-1.2.jar

Place JDBC JAR libraries in path where they can be found:

cp /usr/share/pgsql/jdbc7.1-1.2.jar /var/tomcat6/lib

Java Servlet run under Tomcat, accessing PostgreSQL using JDBC:

Java Servlet source file:
001// File: ShowBedrock.java
002 
003/* A servlet to display the contents of the PostgreSQL Bedrock database */
004 
005import java.io.*;
006import java.sql.*;
007import java.text.*;
008import java.util.*;
009import javax.servlet.*;
010import javax.servlet.http.*;
011 
012public class ShowBedrock extends HttpServlet
013{
014    public String getServletInfo()
015    {
016       return "Servlet connects to PostgreSQL database and displays result of a SELECT";
017    }
018 
019    private Connection dbcon;  // Connection for scope of ShowBedrock
020 
021    // "init" sets up a database connection
022    public void init(ServletConfig config) throws ServletException
023    {
024        String loginUser = "postgres";
025        String loginPasswd = "supersecret";
026        String loginUrl = "jdbc:postgresql://localhost/bedrock";
027 
028        // Load the PostgreSQL driver
029        try
030        {
031              Class.forName("<b>org.postgresql.Driver</b>");
032              dbcon = DriverManager.getConnection(loginUrl, loginUser, loginPasswd);
033        }
034        catch (ClassNotFoundException ex)
035        {
036               System.err.println("ClassNotFoundException: " + ex.getMessage());
037               throw new ServletException("Class not found Error");
038        }
039        catch (SQLException ex)
040        {
041               System.err.println("SQLException: " + ex.getMessage());
042        }
043    }
044 
045    // Use http GET
046 
047    public void doGet(HttpServletRequest request, HttpServletResponse response)
048        throws IOException, ServletException
049    {
050        response.setContentType("text/html");    // Response mime type
051 
052        // Output stream to STDOUT
053        PrintWriter out = response.getWriter();
054 
055        out.println("<HTML><Head><Title>Bedrock</Title></Head>");
056        out.println("<Body><H1>Bedrock</H1>");
057         
058        try
059        {
060                // Declare our statement
061                Statement statement = dbcon.createStatement();
062 
063                String query = "SELECT name, dept, ";
064                query +=       "       jobtitle ";
065                query +=       "FROM   employee ";
066 
067                // Perform the query
068                ResultSet rs = statement.executeQuery(query);
069 
070                out.println("<table border>");
071 
072                // Iterate through each row of rs
073                while (rs.next())
074                {
075                   String m_name = rs.getString("name");
076                   String m_dept = rs.getString("dept");
077                   String m_jobtitle = rs.getString("jobtitle");
078                   out.println("<tr>" +
079                               "<td>" + m_name + "</td>" +
080                               "<td>" + m_dept + "</td>" +
081                               "<td>" + m_jobtitle + "</td>" +
082                               "</tr>");
083                }
084 
085                out.println("</table></body></html>");
086                statement.close();
087        }
088        catch(Exception ex)
089        {
090                out.println("<HTML>" +
091                            "<Head><Title>" +
092                            "Bedrock: Error" +
093                            "</Title></Head>\n<Body>" +
094                            "<P>SQL error in doGet: " +
095                            ex.getMessage() + "</P></Body></HTML>");
096                return;
097        }
098        out.close();
099    }
100}

Notes:

  • String loginUrl = "jdbc:postgresql://localhost/bedrock";
    The format for this is jdbc:postgresql:host-name-of-server:port/database-name
    Examples:
    • jdbc:postgresql:bedrock - bedrock is the PostgreSQL database name. See PostgreSQL tutorial.
    • jdbc:postgresql://localhost/bedrock
    • jdbc:postgresql://localhost:5432/bedrock - Default PostgreSQL standard port number is 5432
  • public void doGet(...
    Using http GET request. For http POST operations use doPost
  • String m_name = rs.getString("name");
    One may also use database field names or field numbers. i.e.
    String m_name = rs.getString(1);
    String m_dept = rs.getString(2);

Set CLASSPATH environment variable:

export CLASSPATH=$CLASSPATH:/var/tomcat6/lib/jdbc7.1-1.2.jar

OR export CLASSPATH=/usr/java/j2sdk1.4.0/lib/tools.jar:/usr/java/j2sdk1.4.0/jre/lib/rt.jar:/var/tomcat6/common/lib/servlet.jar:/var/tomcat6/lib/jdbc7.1-1.2.jar

Compile:

[prompt]# cd /var/tomcat6/webapps/examples/WEB-INF/classes
[prompt]# javac ShowBedrock.java

(OR /usr/java/j2sdk1.4.0/bin/javac ShowBedrock.java )
PostgreSQL Configuration: /var/lib/pgsql/data/postgresql.conf

Set: tcpip_socket = true
This allows JDBC to connect to PostgreSQL.

Test:

Results:

Bedrock

Fred Flinstone Quarry Worker Rock Digger
Wilma Flinstone Finance Analyst
Barney Rubble Sales Neighbor
Betty Rubble IT Neighbor


JDBC/PostgreSQL Links:

2) MySQL:

Install and configure a database: YoLinux Tutorial: MySQL and Linux

Download JDBC MySQL JAR file:

  • Install package mysql-connector-java-5.1.17-6.el6.noarch which includes /usr/share/java/mysql-connector-java.jar (sym linked to mysql-connector-java-5.1.17.jar)
    Add JAR file to CLASSPATH. Add mysql-connector-java-5.1.17.jar to your WAR file.
MySQL Admin:

"GRANT ALL PRIVILEGES ON bedrock to 'user@hostname' identified by 'password';
FLUSH PRIVILEGES

where hostname is localhost.localdomain (not localhost on default Red Hat installation)

Java Servlet run under Tomcat, accessing MySQL using JDBC:

Java Servlet source file: (Note that it does the same thing as the PostgrSQL example above but it is written with a different style.)
01// File: ShowBedrock.java
02 
03/* A servlet to display the contents of the MySQL Bedrock database */
04 
05import java.io.*;
06import java.net.*;
07import java.sql.*;
08import java.text.*;
09import java.util.*;
10import javax.servlet.*;
11import javax.servlet.http.*;
12 
13public class ShowBedrock extends HttpServlet
14{
15    public String getServletInfo()
16    {
17       return "Servlet connects to MySQL database and displays result of a SELECT";
18    }
19 
20    // Use http GET
21 
22    public void doGet(HttpServletRequest request, HttpServletResponse response)
23        throws IOException, ServletException
24    {
25        String loginUser = "Dude1";
26        String loginPasswd = "SuperSecret";
27        String loginUrl = "jdbc:mysql://localhost:3306/bedrock";
28 
29        response.setContentType("text/html");    // Response mime type
30 
31        // Output stream to STDOUT
32        PrintWriter out = response.getWriter();
33 
34        out.println("<HTML><HEAD><TITLE>Bedrock</TITLE></HEAD>");
35        out.println("<BODY><H1>Bedrock</H1>");
36 
37        // Load the mm.MySQL driver
38        try
39           {
40              Class.forName("org.gjt.mm.mysql.Driver");
41              Connection dbcon = DriverManager.getConnection(loginUrl, loginUser, loginPasswd);
42              // Declare our statement
43              Statement statement = dbcon.createStatement();
44 
45              String query = "SELECT name, dept, ";
46              query +=       "       jobtitle ";
47              query +=       "FROM   employee ";
48 
49              // Perform the query
50              ResultSet rs = statement.executeQuery(query);
51 
52              out.println("<TABLE border>");
53 
54              // Iterate through each row of rs
55              while (rs.next())
56              {
57                  String m_name = rs.getString("name");
58                  String m_dept = rs.getString("dept");
59                  String m_jobtitle = rs.getString("jobtitle");
60                  out.println("<tr>" +
61                              "<td>" + m_name + "</td>" +
62                              "<td>" + m_dept + "</td>" +
63                              "<td>" + m_jobtitle + "</td>" +
64                              "</tr>");
65              }
66 
67              out.println("</TABLE>");
68 
69              rs.close();
70              statement.close();
71              dbcon.close();
72            }
73        catch (SQLException ex) {
74              while (ex != null) {
75                    System.out.println ("SQL Exception:  " + ex.getMessage ());
76                    ex = ex.getNextException ();
77                // end while
78            // end catch SQLException
79 
80        catch(java.lang.Exception ex)
81            {
82                out.println("<HTML>" +
83                            "<HEAD><TITLE>" +
84                            "Bedrock: Error" +
85                            "</TITLE></HEAD>\n<BODY>" +
86                            "<P>SQL error in doGet: " +
87                            ex.getMessage() + "</P></BODY></HTML>");
88                return;
89            }
90         out.close();
91    }
92}
Compile:
[prompt]# export CLASSPATH=/var/tomcat6/common/lib/mysql-connector-java-5.1.17.jar:$CLASSPATH
[prompt]# cd /var/tomcat6/webapps/examples/WEB-INF/classes
[prompt]# javac ShowBedrock.java

(ORexport CLASSPATH=/usr/java/latest/lib/tools.jar:/usr/java/latest/jre/lib/rt.jar:/var/tomcat6/common/lib/servlet.jar:/var/tomcat6/lib/mysql-connector-java-5.1.17.jar )
(OR /usr/java/j2sdk1.4.0/bin/javac ShowBedrock.java )

Test:

Notes:

  • [Potential Pitfall]: The MySQL "user" table will define users and their host. I made the mistake of using "localhost" when the host name returned by the Unix command "hostname" was different. When the servlet tried to connect to the database it was refused.
    [prompt]$ hostname
    
    superserver [prompt]$ mysql -h localhost -u root -p ... mysql> use mysql mysql> select user,host from user; +-------+------------+ | user | host | +-------+------------+ | root | | | Dude1 | localhost | +-------+------------+ mysql> update user set Host='superserver' where User='Dude1'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0


Links:

Java JDBC:

Java JDBC programs require the package: java.sql. Contained within this package are:

  • Classes:
    • Date
    • DriverManager
    • DriverPropertyInfo
    • Time
    • Timestamp
    • Types
  • Interfaces:
    • CallableStatement
    • Connection
    • DatabaseMetaData
    • Driver
    • PreparedStatement
    • ResultSet
    • ResultMetaData
    • Statement

JDBC Links:

Java Server Pages (JSP):

Basic JSP elements:

  • <jsp: ... %> : Define/execute Java statements.
    Example:
       <jsp:usebean id="clock" scope="page" class="dates.JspCalendar" type="dates.JspCalendar">
       Year: is  <jsp:getProperty name="clock" property="year"/>
       <BR>
       Month: is  <jsp:getProperty name="clock" property="month"/>
        </jsp:usebean>
              
  • <% ... %> : Execute Java statements. Nothing displayed.
    Example: <% numguess.reset(); %>
  • <%= ... %> : Execute Java expression and place results here.
    Example: Calendar:<%= table.getDate() %>
  • <%@ ... %> : Declare Java variable or method.
    Example:
       <%@ page language="java" import="cal.*" %>
    <jsp:useBean id="table" scope="session" class="cal.TableBean" />
JSP's are rarely self contained. JSP's most often require use of classes and methods defined in Java programs.

The samples delivered with Tomcat show numerous JSP examples and the source code:

Links:

Books:

"Core Java 2, Volume 1: Fundamentals "
by Cay S. Horstmann, Gary Cornell
ISBN # 0132354764, Prentice Hall PTR 8th edition

The industry standard. Need I say more?

Amazon.com
"Core Java 2: Volume 2 Advanced Features "
by Cay S. Horstmann, Gary Cornell
ISBN # 0132354799, Prentice Hall PTR 8th edition

The industry standard. Need I say more?

Amazon.com
"Core Java Server Faces"
by David Geary, Cay S. Horstmann
ISBN # 0131738860, Prentice Hall PTR 2nd edition

Amazon.com
Tomcat: The Definitive Guide
by Jason Brittain, Ian F. Darwin
ISBN # 0596003188 O'Reilly & Associates; 1st Edition edition

Amazon.com
"Professional Apache Tomcat"
by Chanoch Wiggers, Ben Galbraith, Vivek Chopra, Sing Li, Debashish Bhattacharjee, Amit Bakore, Romin Irani, Sandip Bhattacharya, Chad Fowler
ISBN # 0764543725 Wrox

Amazon.com
Apache Jakarta-Tomcat
by James Goodwill
ISBN # 1893115364, APress

Amazon.com
Apache Tomcat Security Handbook
by Vivek Chopra, Ben Galbriaths, Brian Rickabaugh, Gotham Pollysetty, John Turner
ISBN # 1861008309, Wrox Press

Amazon.com
"JSP, Servlets, and MySQL"
by David Harms
ISBN # 0764547879, Hungry Minds, Inc

Amazon.com
"MySQL"
by Paul DuBois, Michael Widenius
ISBN # 0735709211, New Riders Publishing

Amazon.com
"Manageing and Using MySQL"
by George Reese, Randy Jay Yarger, Tim King
ISBN # 0596002114, O'Reilly

Amazon.com
PostgreSQL Essential Reference
by Barry Stinson
ISBN #0735711216, New Riders

Amazon.com
PostgreSQL: Developer's Handbook
by Ewald Geschwinde, Hans-Juergen Schoenig, Hans-Jurgen Schonig
ISBN #0672322609, SAMS

Amazon.com
Practical PostgreSQL
John C. Worsley, Joshua D. Drake
ISBN #1565928466, O'Reilly

Amazon.com
Beginning Databases with PostgreSQL
by Richard Stones, Neil Matthew
ISBN #1861005156, Wrox Press Inc

Amazon.com