Taming Tomcat, Day 1: The Basics

Author and presenter: Simon Brooke.

The full text of this presentation is online at <URL: http://www.weft.co.uk/library/tomcat/>

Written March-April 2006; $Revision: 1.9 $ of $Date: 2006-04-28$

Changes to the presentation since your handouts were printed are highlighted like this.

Simon Brooke, 21 Main Street, Auchencairn, DG7 1QU, Scotland.

Day 2: Development and Adminsitrationnext


Before we start...


Programme for Today

In sh'Allah...

'Good teaching is one-fourth preparation and three-fourths theater' - let's hope so!


What I'm trying to achieve today


What is Tomcat


The Internet and the Web

Open, heterogenous network of networks, carrying distributed hypertext

Open:
the standards are published, and are not protected by patents, non-disclosure agreements, and so on - anyone can copy them.
Heterogenous:
the standards are not based on the facilities of any one proprietary sort of computer - any computer can be connected
Networks of networks:
not every computer everywhere has to be able to connect to the same network standards, provided that the networks themselves can intercommunicate.

A brief history of Distributed Hypertext

or 'none of this is new' part one

Project Xanadu, Ted Nelson 1960

Distributed hypertext over heterogenous networks

TCP/IP, Xerox PARC, 1970s

Transmission of data over unreliable networks of networks

HTML, Tim Berners-Lee, CERN, 1990

Distributed hypertext over heterogenous networks - much simpler than Xanadu


Forms in HTML


Cheap Client-Server Lego

This is new!


Java

or 'none of this is new' part two


A brief history of programming languages


LISP: John McCarthy, 1959


BCPL: Martin Richards, Cambridge University, 1969


C: Thompson & Richie, Bell Labs, 1972


Smalltalk: Goldberg, Kay and others, Xerox PARC, 1973


Oak: James Gosling, Sun Microsystems, 1990


Java


Server-side Java


Java was not conceived as a server-side language


Java has substantial problems as a server-side language


About Web servers


HTTPD in 100 lines

!/bin/bash

#########################################################################
#                                                                       #
#            Project: Gild                                              #
#            http                                                       #
#                                                                       #
#            Purpose: HTTP 0.9 handler for GILD. Handles http requests  #
#               reasonably accurately, considering it's under 100 lines #
#               of shell-script.                                        #
#                                                                       #
#            Author   : Simon Brooke                                    #
#            Copyright: (c) Simon Brooke 1997                           #
#            Version  : 0.1                                             #
#            Created  : 10th October 1997                               #
#                                                                       #
#########################################################################

SERVER_ROOT="/etc/local/etc/gild/httpd"
DOCUMENT_ROOT="$SERVER_ROOT/htdocs/"
AGENT_NAME="GILD_http_handler/0.1"

now=`date "+%a, %d %b %Y %k-%M-%S"`

read command file protocol

case $command in
    "HEAD"|"Head"|"head")   ;;          # that's OK;
    "GET"|"Get"|"get"   )   ;;          # So's that...
    *   )       cat $SERVER_ROOT/error/501.html;
                echo "$now: $REMOTE_HOST: Unknown command [$command]" \
                    >> $SERVER_ROOT/logs/error_log;
                exit 0;;  
esac

rq_file=$file

if [ -n $file ]
then
    file=`echo "$DOCUMENT_ROOT$file"`

    if [ -d $file ]                     # if it's a directory, look for it's
                                        # index...
    then
        file=`echo "$file/index.html"`
    fi

    if [ -r $file ]
    then
        length=`ls -l $file | awk '{print $5}'`

        ftype=`file $file | sed 's/[^:]*: //' | awk '{ print $1}'`

        case $ftype in
            "HTML"      )   type=text/html;;
            "ascii"     )   type=text/plain;;
            "english"   )   type=text/plain;;
            "a"         )   type=text/plain;;   # probably a shell script!
            "GIF"       )   type=image/gif;;
            "JPEG"      )   type=image/jpeg;;
            *           )   type=x-unknown/unknown;;
        esac

        echo "HTTP/0.9 200 OK"
        echo "Date: $now"
        echo "Server: $AGENT_NAME"
        echo "Content-Type: $type"
        echo "Content-Length: $length"
        echo ""

        case $command in
            "HEAD"|"Head"|"head")   exit 0;;
            "GET"|"Get"|"get"   )   cat $file;;
        esac

        echo "$now: $REMOTE_HOST: $command: $rq_file" \
                    >> $SERVER_ROOT/logs/access_log
    else                            # didn't find it; report and log
        cat $SERVER_ROOT/error/404.html
        echo "$now: $REMOTE_HOST: No such file [$rq_file]" \
                    >> $SERVER_ROOT/logs/error_log
    fi
fi
exit 0                              # yes, I know it _shouldn't_ be necessary

About CGI


Java CGI: Performance


Why was the performance so bad?


Difference between Servlets and CGIs


Why Tomcat?


Why Tomcat


Reprise: What is Tomcat


Simple install: Windows


Simple Install: Debian


Simple install: Debian (ii)


Simple install


Exercise: Install Tomcat


[Break]


Basic Configuration


server.xml Brief highlights


Things you may want to change from the defaults


Top-level web.xml


Integration


Why Integrate?


Integration Strategies


Integration: Side-by-side


Exercise: Side by side


Integration: One in front of the other


Integration: Connectors


Connectors: brief history


mod_jk: Configuring


Major Gotcha: Apache HTTPD 2.2


From the Apache HTTPD side: getting and installing mod_jk

This is not as straightforward as it could be!


From the Apache HTTPD side: httpd.conf or apache2.conf


From the Apache HTTPD side: workers.properties


From the Tomcat side


Digression: 'Apache'


Exercise: One in front of the other


[Lunch]


More complex Webapps


Exercise: installing more complex webapps


Stress testing


Installing JMeter


Starting JMeter


Configuring JMeter


the Test Plan


Exercise: Running JMeter


Things to do with JMeter


Break


Building a Webapp with JSP


Introduction to JSP


Why I don't like/use JSP


Setting up the framework of your Webapp


A page which includes dynamic content


How's that?


Doing it right


Edit your page a little


A page which performs a calculation

<?xml version="1.0" encoding="iso-8859-1"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" 
  xmlns:html="http://www.w3.org/1999/xhtml"
  version="1.2">
  <jsp:text>
    <html:html
      xmlns:html="http://www.w3.org/1999/xhtml">
      <html:head>
        <html:title>Fourth JSP Page</html:title>
      </html:head>
      <html:body>
        <!-- this is how we do imports in JSP -->
        <jsp:directive.page import="java.util.*" />
        <!-- this is how we declare variables -->
        <jsp:declaration>
          GregorianCalendar greg = 
            new GregorianCalendar();
        </jsp:declaration>
        <!-- this is how we embed arbitrary code -->
        <jsp:scriptlet>
          greg.add( Calendar.MONTH, 1);
        </jsp:scriptlet>
        <html:h1>Hello world!</html:h1>

        <html:p>In one month it will be 
          <jsp:expression>greg.getTime()</jsp:expression>
        </html:p>
      </html:body>
    </html:html>
  </jsp:text>
</jsp:root>

In old syntax


About 'Beans'


A page which uses a 'Bean'

<?xml version="1.0" encoding="iso-8859-1"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" 
  xmlns:html="http://www.w3.org/1999/xhtml"
  version="1.2">
  <jsp:text>
    <html:html
      xmlns:html="http://www.w3.org/1999/xhtml">
      <html:head>
        <html:title>Fifth JSP Page</html:title>
      </html:head>
      <html:body>
        <jsp:useBean id="clock" class="java.util.Date"/>
        <html:h1>Hello World!</html:h1>

        <html:p>The time is now</html:p>
        <html:ul>
          <html:li>
            Hours: 
            <jsp:getProperty name="clock" property="hours"/>
          </html:li>
          <html:li>
            Minutes: 
            <jsp:getProperty name="clock" property="minutes"/>
          </html:li>
        </html:ul>
      </html:body>
    </html:html>
  </jsp:text>
</jsp:root>

In old syntax


Accessing passed parameters

<?xml version="1.0" encoding="iso-8859-1"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" 
  xmlns:html="http://www.w3.org/1999/xhtml"
  version="1.2">
  <jsp:text>
    <html:html
      xmlns:html="http://www.w3.org/1999/xhtml">
      <html:head>
        <html:title>Sixth JSP Page</html:title>
      </html:head>
      <html:body>
        <jsp:directive.page import="java.util.*" />
        <jsp:declaration>
          GregorianCalendar greg = 
            new GregorianCalendar();
          Integer month = new Integer( greg.get( Calendar.MONTH));
          Integer offset = new Integer( 0);
          String value = null;
        </jsp:declaration>
        <jsp:scriptlet>
          value = request.getParameter( "offset");
          if ( value != null)
          {
            try
            {
              offset = new Integer( Integer.parseInt( value));
            }
            catch ( NumberFormatException nfe)
            {
              System.out.println( value + " wasn't a number");
            }
          }
          greg.add( Calendar.MONTH, offset.intValue());
        </jsp:scriptlet>

        <html:h1>Hello World!</html:h1>

        <html:p>In 
          <jsp:expression>offset.toString()</jsp:expression>
          months is will be
          <jsp:expression>greg.getTime()</jsp:expression>
        </html:p>
        <html:form action="jsp6.jsp">
          <html:label>Input a number</html:label>
          <html:input name="offset"/>
        </html:form>
      </html:body>
    </html:html>
  </jsp:text>
</jsp:root>

In old syntax

    <html>
          <head>
                <title>Sixth JSP Page</title>
          </head>
          <body>
            <%@ page import="java.util.*" %>
            <%! GregorianCalendar greg = 
                 new GregorianCalendar();
                   Integer month = new Integer( greg.get( Calendar.MONTH));
                   Integer offset = new Integer( 0);
                   String value = null; %>
            <%
                  value = request.getParameter( "offset");
                  if ( value != null)
          {
            try
            {
              offset = new Integer( Integer.parseInt( value));
            }
            catch ( NumberFormatException nfe)
            {
              System.out.println( value + " wasn't a number");
            }
          }
          greg.add( Calendar.MONTH, offset.intValue());
            %>

                <h1>Hello World!</h1>

                <p>In 
              <%= offset.toString() %>
              months is will be
              <%= greg.getTime() %>
        </p>
        <form action="jsp6.jsp">
          <label>Input a number</label>
          <input name="offset"/>
        </form>
          </body>
    </html>

Exercise: build a simple Webapp with JSP


Questions and Suggestions for tomorrow