Tomcat Server Configuration

Staying on the road with less difficulty, the requirements are basically as follows:

(1)  Requests for some web pages on our domain name ….. to be processed by the Java Tomcat server, and

(2)  The remaining pages to be processed by the Apache web server.

An easy way to think of the two is to have all the html pages processed by the Apache web server, and all other url requests to be processed  by programs written in the Java programming language and processed by the Tomcat web server.

For example:

               http://www.programmer.com.au/form —>  Form

That is, the web page “form” will then be processed by the Tomcat web server, and not Apache. 

Apache listens on port 80 for all new connections to our domain programmer.com.au ( and  the Tomcat server does not ) so we want Apache to pass on this request for “form” to the Tomcat Server ( which listens on port 8009 for such requests from Apache ).

Note: the firewall previously set up here, does not need changing to prevent access to port 8009 from outside the server, as the default for new connection from outside is to deny them.

The 8080 port number used to access the manger for the Tomcat server is another matter, which is explained below.

Apache Setup

The configuration file in Apache is easy enough, and for our first example looks like this:

<VirtualHost 259.155.255.27:80>
        ServerName programmer.com.au
        ServerAlias www.programmer.com.au
        ServerAdmin webmaster@localhost
        DocumentRoot /usr/local/blogs/programmer
        ErrorLog /var/log/apache2/programmer-error.log
        CustomLog /var/log/apache2/programmer_access.log combined
        DirectoryIndex index.html index.php

        # Send requests for  /form* to the worker channel named w1
        JkMount  /form* w1
</VirtualHost>

All that  was need was the JkMount line linking /form to the w1 channel to the Tomcat server.

Configuration for Tomcat on the pother hand, is somewhat more involved.

Tomcat Setup

The setup entails informing the Tomcat server that a request for “/form” coming from Apache ( via port 8009 ), is to be processed by the Java Servlet called Form, say.

Unlike the Apache web server,  the Tomcat server is configured using XML formatted configuration files and particular structures of the file system.  Many file and directory names have special meaning and can not be changed or moved; un-unix like names such as WEB-INF, META_INF, ROOT, localhost, and Catalina, among others.  Therefore, to get things working this side of Christmas, best practice is to stay with the proven working examples here and elsewhere, and the meaning of these names will become clear with further use.

Step 1. Get the Manager and Host-Manager applications working in the Tomcat server.  These mangers are needed to monitor the Java Servlets, which are especially useful in regulating the number of open running sessions.

(a)  Enter in a user name and password to access these two managers.

This can be tricky as there are XML tags called “roles” which have specific values that must be assigned in a certain way, otherwise your login will fail.  This example works however and it’s best to set these up before trying to run the Tomcat server, to avoid having the frustration of wondering whether or not to reset possible past cached login failures or something else.  Here is an abbreviated example that actually works:

# vi   /usr/local/tomcat/conf/tomcat-users.xml

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">

  <role rolename="manager-gui"/>
  <role rolename="admin-gui"/>
  <role rolename="manager"/>
  <user username="james" password="my-secret-password" 
                                 roles="admin-gui,manager,manager-gui"/>
</tomcat-users>

(b) Enter in your local ip address that you will be accessing these two  applications. 

Again, this is needed for access.   Two configuation files called “context.xml” are need to be changed, one located in /usr/local/tomcat/webapps/manager/META-INF and the other in //usr/local/tomcat/webapps/host-manager/META-INF.

Assuming the ip address of the computer being used to access these manager application is “279.214.85.1” etc, here is a simplified example of the changes needed:

#  vi  /usr/local/tomcat/webapps/manager/META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true" >
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|279\.214\.85\.\d+" />
        <Resources cachingAllowed="false" />
</Context>

The same goes for the host-manager: at /usr/local/tomcat/webapps/host-manager/META-INF/context.xml

Note: Also, in addtion to the above, the fire wall “iptables” needs to open a path through from outside to the port 8080, as the default setup so far is for “iptables” to deny all new connections from outseide, unless explicitly allowed.

The command to insert this new rule is as follows:

# iptables  -I INPUT  12  -s 279.214.85.1/32 -p tcp -m tcp –dport 8080 -j ACCEPT

where “279.214.85.1” say, is the ip address of your outside computer that will be used to access the Tomcat servers host mangers.

(c)  Now we can enter into our browser, the ip address of the Tomcat server at port 8080 and it will show up with a welcome page, and links to the Manager and Host Manger.

#  systemctl start tomcat
#  systemctl  status tomcat
#  systemctl  stop tomcat

Step 2.  Configure the domain

(a)  Add in the domain name

All we need do to add in our domain name is to add two lines into the server file with the Alias tag.  Following is a simplified example that works:

# vi  /usr/local/tomcat/conf/ server.xml

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/>
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="/usr/local/tomcat/conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" 
                                                                             redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
             <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                     resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
                            deployOnStartup="true"
                                               unpackWARs="true"
                                               autoDeploy="false">
       <Valve className="org.apache.catalina.valves.AccessLogValve"
                              directory="logs"
                              prefix="localhost_access_log"
                              suffix=".txt"
                              pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      <Alias>programmer.com.au</Alias>
     <Alias>www.programmer.com.au</Alias>
      </Host>
    </Engine>
  </Service>
</Server>

(b)  Configure the file structure.

# ls -la   /usr/local/tomcat

total 256

drwxr-sr-x 10   root staff       4096 May  9 10:34 .
drwxrwsr-x 17  root staff       4096 Apr 29 14:20 ..
drwxrwx---  2   root tomcat   4096 Apr 30 13:56 bin
drwxrwx---  5   root tomcat   4096 May  9 10:36 conf
drwxrwx---  2   root tomcat   4096 Apr 28 11:05 lib
-rw-rw----  1     root tomcat   57092 Apr 13 22:58 LICENSE
drwxrwx---  2   root tomcat   4096 May  8 08:15 logs
-rw-rw----  1     root tomcat   1723 Apr 13 22:58 NOTICE
-rw-rw----  1     root tomcat   7064 Apr 13 22:58 RELEASE-NOTES
-rw-rw----  1     root tomcat   15946 Apr 13 22:58 RUNNING.txt
drwxrwx---  2   root tomcat   4096 May  8 17:04 temp
drwxr-x---  7    root tomcat    4096 May  8 14:30 webapps
drwxrwsr-x  3 root tomcat     4096 May  8 12:26 work

Inside the webapps directory, lives the java code that the Tomcat server will run to process the web requests.

# ls -la  /usr/local/tomcat/webapps

total 28
drwxr-x---          7 root tomcat 4096 May  8 14:30 .
drwxr-sr-x       10 root tomcat 4096 May  9 10:34 ..
drwxr-x---       14 root tomcat 4096 Apr 28 11:05 docs
drwxr-x---        6 root tomcat 4096 Apr 28 11:05 examples
drwxr-x---       5 root tomcat 4096 May  5 15:13 host-manager
drwxr-x---       5 root tomcat 4096 Apr 28 11:05 manager
drwxr-x---       3 root tomcat 4096 May  8 14:29 ROOT

The directory that the Tomcat server accesses for the domain is: /usr/local/tomcat/webapps/ROOT

#  ls -la  /usr/local/tomcat/webapps/ROOT

total 12
drwxr-x--- 3 root tomcat 4096 May  8 14:29 .
drwxr-x--- 7 root tomcat 4096 May  8 14:30 ..
drwxr-xr-x 5 root tomcat 4096 May  8 14:29 WEB-INF

Inside the WEB-INF directory, must exist the following:

#  ls -la  /usr/local/tomcat/webapps/ROOT/WEB-INF

total 24
drwxr-xr-x 5 root tomcat 4096 May  8 14:29 .
drwxr-x--- 3 root tomcat 4096 May  8 14:29 ..
drwxr-xr-x 2 root tomcat 4096 May  8 14:29 classes
drwxr-x--- 2 root tomcat 4096 May  8 14:29 lib
drwxr-x--- 2 root tomcat 4096 May  8 14:29 listeners
-rw-r-xr-- 1 root tomcat 2192 May  8 14:29 web.xml

The classes directory is where to copy in our Java class files that the Tomcat server will run.

The file web.xml is where to tie the calling of a web page ( say Form ), to the execution of the relevant Java class servlet ( ie, a program ) that we copied into the classes directory here.

Access to the managers will now be directly through http://programmer.com.au:8080/host-manager/html and http://programmer.com.au:8080/manager/html.

Step 3.  Configure the mapping to Java classes

In other words, this is where a url is tied to running a computer program written in the Java programming language.  These java programs are of course, generally referred to as Servlets.  Basically though, servlets can be thought of as just being slightly different from other types of programs written in java, simply because they run inside a web server’s java interpretor ( whoever that is spelt – my word process dosn’t know either ). 

Some language theory might disagree in the detail ( and would be right ) but thinking simply here works, at the start, at least .

So the configuation file that defines the links between the url’s and the java servlets is always called “web.xml”.  In our first example, the url containing “Form” is to call the java servlet “Form”.  That is:  http://programmer.com.au/Form –>  Form.class

The following is how a cut down working configuration file looks in the Tomcat server:

# cat  /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1"
  metadata-complete="true">
    <description> Our First Java Servlet </description>
    <display-name>***** Our First Java Servlet *****</display-name>
    <session-config>
<session-timeout>60</session-timeout>
    </session-config>
    <Manager classname="org.apache.catalina.session.StandardManager"
maxInactiveInterval="7250"/>

    <servlet>
      <servlet-name>form</servlet-name>
 <display-name>Form ..</display-name>
      <servlet-class>Form</servlet-class>
     <init-param>
       <param-name>debug</param-name>
       <param-value>11</param-value>
     </init-param>

    </servlet>
    <servlet-mapping>
        <servlet-name>form</servlet-name>
        <url-pattern>/Form</url-pattern>
    </servlet-mapping>
</web-app>

As can be seen above, the url pattern /Form, is tied to a tag called in this example, an arbitrary name called  form.  This form name is also tied to the java class Form, thereby tying in a round about sort of way, the url /Form to the java class Form.

The main difficulty with this approach is that as applications grow in size, the number of java classes naturally increase in number and the web.xml configuration file can become rather large.  Finding a mis-matched pair in a long list can become difficult, as the Tomcat server simply gives a general error and will not start.

One solution is to run a small script that generates these xml pairs, thereby eliminating any typing mis-matches.  Alternatively, some in frustration, may prefer having one java servlet that first responds to all url requests and then handing it onto the appropriate java servlet down the line, but this kinda takes away many of the benefits of having a Servlet web server.

If the java class file have the same name as the url pattern, its easy then  to create the xml mapping with an awk script, such as this:

# cd /usr/local/tomcat/webapps//ROOT/WEB-INF/classes
#  ls -1 *.class | awk -f web.awk
# cat web.awk
# awk program to create the web.xml mapping
# from the classes directory
BEGIN { FS=”.”; }
{
    print “\t<servlet>”;
    print “\t\t<servlet-name>s” NR “</servlet-name>”;
    print “\t\t<display-name>” $1 “..</display-name>”;
    print “\t\t<servlet-class>” $1 “</servlet-class>”;
    print “\t\t <init-param>”;
    print “\t\t    <param-name>debug</param-name>”;
    print “\t\t   <param-value>1</param-value>”;
    print “\t\t </init-param>”;
    print “\t</servlet>”;
    print “”;
    print “\t<servlet-mapping>”;
    print “\t\t <servlet-name>s” NR “</servlet-name>”;
    print “\t\t <url-pattern>/” $1 “</url-pattern>”;
    print “\t</servlet-mapping>”;
    print “”;
}

#  systemctl  reload tomcat

 

Next, onto writing some java programs 🙂


Problem starts

—————–

08-May-2017 12:49:45.729 SEVERE [Catalina-startStop-1] org.apache.catalina.core.ContainerBase.startInternal A child container failed during start

java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]

at java.util.concurrent.FutureTask.report(FutureTask.java:122)

Probably something wrong with the directory structures.

—————-

© 2017, James Harry Burton. All rights reserved.