Benutzer-Werkzeuge

Webseiten-Werkzeuge


Action disabled: source
tachtler:apache_tomcat_5

Apache Tomcat 5

Apache Tomcat ist eine Implementierung der Java Servlet und der JavaServer Pages Technologie. Die Java Servlet und die JavaServer Pages Spezifikationen sind hier Java Community Process beschrieben.

Installation

Für einen erfolgreichen Betrieb eines Apache Tomcat Applications Servers sind folgende Komponenten erforderlich:

Eine Beschreibung zur Installation von von Sun's JDK ist ebenfalls in diesem dokuwiki unter installation_von_sun_s_jdk beschrieben.

  • tomcat5.i386 (tomcat5) - Apache Servlet/JSP Engine, RI for Servlet 2.4/JSP 2.0 API
  • tomcat5-admin-webapps.i386 (tomcat5-admin-webapps) - The administrative web applications for Jakarta Tomcat
  • tomcat5-common-lib.i386 (tomcat5-common-lib) - Libraries needed to run the Tomcat Web container (part)
  • tomcat5-jasper.i386 (tomcat5-jasper) - Compiler JARs and associated scripts for tomcat5
  • tomcat5-jsp-2.0-api.i386 (tomcat5-jsp-2.0-api) - Jakarta Tomcat Servlet and JSP implementation classes
  • tomcat5-server-lib.i386 (tomcat5-server-lib) - Libraries needed to run the Tomcat Web container (part)
  • tomcat5-servlet-2.4-api.i386 (tomcat5-servlet-2.4-api) - Jakarta Tomcat Servlet implementation classes
  • tomcat5-webapps.i386 (tomcat5-webapps) - Web applications for Jakarta Tomcat

Nach einer erfolgreichen Installation der genannten Pakete, kann mit folgendem Befehl die aktuelle Version der Apache Tomcat Installation überprüft werden und sollte in etwa wie nachfolgend dargestellt aussehen:

# service tomcat5 version
Server version: Apache Tomcat/5.5.23
Server built:   Aug 27 2008 07:11:38
Server number:  5.5.23.0
OS Name:        Linux
OS Version:     2.6.18-92.1.13.el5
Architecture:   i386
JVM Version:    1.6.0_06-b02
JVM Vendor:     Sun Microsystems Inc.

Konfiguration

Folgende Konfigurationsdateien sollten mindestens angepasst werden:

  • /etc/init.d/tomcat5 - Start/Stop usw. -Script für Apache Tomcat
  • /etc/tomcat5/tomcat5.conf - Haupt-Konfigurationsdatei
  • /etc/tomcat5/server.xml - Server-Konfiguration (Ports usw.)
  • /etc/tomcat5/tomcat-users.xml - Benutzerverwaltung

Ab hier werden root-Rechte zur Ausführung der nachfolgenden Befehle benötigt. Um root zu werden geben Sie bitte folgenden Befehl ein:

$ su -
Password: 

/etc/init.d/tomcat5

Die Änderungen betreffen das Start/Stop usw. -Script und dienen der Stabilität.

:!: Falls diese Änderungen nicht vorgenommen werden und die Log-Datei /var/log/tomcat5/catalina.out nicht mit den entsprechenden Rechten existiert, ist ein Start unmöglich!

:!: Der Standard-Port 8080 wurde auf 8000 abgeändert. Dies hat keine tiefere Bedeutung und soll nur die Möglichkeit einer solchen Änderung demonstrieren!

Es gibt auch noch einige kosmetische Anpassungen (welche vernachlässigt werden könnten).

Die relevanten Änderungen diesbezüglich sind mit einem Kommentar

# Tachtler

versehen.

#!/bin/bash
#
# tomcat5      This shell script takes care of starting and stopping Tomcat
#
# chkconfig: - 80 20
#
### BEGIN INIT INFO
# Provides: tomcat5
# Required-Start: $network $syslog
# Required-Stop: $network $syslog
# Default-Start:
# Default-Stop:
# Description: Release implementation for Servlet 2.4 and JSP 2.0
# Short-Description: start and stop tomcat
### END INIT INFO
#
# - originally written by Henri Gomez, Keith Irwin, and Nicolas Mailhot
# - heavily rewritten by Deepak Bhole and Jason Corley
#
 
##############################################################################
# Script-Name : tomcat5                                                      #
# Description : This script is normaly placed in /etc/init.d and is the      #
#               standard script for using the standard CentOS tomcat5        #
#               installation. Modified, because if /var/log/tomcat5/         #
#               catalina.out doesn't exist, /usr/bin/dtomcat5 failed.        #
#               Modifications see "Tachtler"-Tags.                           #
# Last update : 19.06.2008                                                   #
# Version     : 1.00                                                         #
##############################################################################
 
##############################################################################
#                                H I S T O R Y                               #
##############################################################################
# Version     : x.xx                                                         #
# Description : <Description>                                                #
# -------------------------------------------------------------------------- #
# Version     : x.xx                                                         #
# Description : <Description>                                                #
# -------------------------------------------------------------------------- #
##############################################################################
 
# commented out until the RHEL and FC daemon functions converge
# Source the function library
if [ -r "/etc/rc.d/init.d/functions" ]; then
    . /etc/rc.d/init.d/functions
fi
 
NAME="$(basename $0)"
unset ISBOOT
if [ "${NAME:0:1}" = "S" -o "${NAME:0:1}" = "K" ]; then
    NAME="${NAME:3}"
    ISBOOT="1"
fi
 
# For SELinux we need to use 'runuser' not 'su'
if [ -x "/sbin/runuser" ]; then
    SU="/sbin/runuser"
else
    SU="su"
fi
 
# Get the tomcat config (use this for environment specific settings)
TOMCAT_CFG="/etc/tomcat5/tomcat5.conf"
if [ -r "$TOMCAT_CFG" ]; then
    . ${TOMCAT_CFG}
fi
 
# Get instance specific config file
if [ -r "/etc/sysconfig/${NAME}" ]; then
    . /etc/sysconfig/${NAME}
fi
 
# Define which connector port to use
# Tachtler
# default: CONNECTOR_PORT="${CONNECTOR_PORT:-8080}"
CONNECTOR_PORT="${CONNECTOR_PORT:-8000}"
 
# Path to the tomcat launch script
TOMCAT_SCRIPT="/usr/bin/dtomcat5"
 
# Path to the script that will refresh jar symlinks on startup
TOMCAT_RELINK_SCRIPT="${CATALINA_HOME}/bin/relink"
 
# Tomcat program name
TOMCAT_PROG="$NAME"
 
# Define the tomcat username
TOMCAT_USER="${TOMCAT_USER:-tomcat}"
 
# Define the tomcat log file
TOMCAT_LOG="${TOMCAT_LOG:-/var/log/tomcat5/catalina.out}"
 
RETVAL="0"
 
# remove when the RHEL and FC daemon functions converge
# (pulled from /etc/rc.d/init.d/functions)
# function checkpid() {
#    local i
#    for i in $* ; do
#        if [ -d "/proc/${i}" ]; then
#            return 0
#        fi
#    done
#    return 1
# }
 
# remove when the RHEL and FC daemon functions converge
# (pulled from /etc/rc.d/init.d/functions)
# function echo_failure() {
#    echo -en "\\033[60G"
#    echo -n "[  "
#    echo -n $"FAILED"
#    echo -n "  ]"
#    echo -ne "\r"
#    return 1
# }
 
# remove when the RHEL and FC daemon functions converge
# (pulled from /etc/rc.d/init.d/functions)
# function echo_success() {
#    echo -en "\\033[60G"
#    echo -n "[  "
#    echo -n $"OK"
#    echo -n "  ]"
#    echo -ne "\r"
#    return 0
# }
 
# Look for open ports, as the function name might imply
function findFreePorts() {
    local isSet1="false"
    local isSet2="false"
    local isSet3="false"
    local lower="8000"
    randomPort1="0"
    randomPort2="0"
    randomPort3="0"
    local -a listeners="( $(
                        netstat -ntl | \
                        awk '/^tcp/ {gsub("(.)*:", "", $4); print $4}'
                    ) )"
    while [ "$isSet1" = "false" ] || \
          [ "$isSet2" = "false" ] || \
          [ "$isSet3" = "false" ]; do
        let port="${lower}+${RANDOM:0:4}"
        if [ -z `expr " ${listeners[*]} " : ".*\( $port \).*"` ]; then
            if [ "$isSet1" = "false" ]; then
                export randomPort1="$port"
                isSet1="true"
            elif [ "$isSet2" = "false" ]; then
                export randomPort2="$port"
                isSet2="true"
            elif [ "$isSet3" = "false" ]; then
                export randomPort3="$port"
                isSet3="true"
            fi
        fi
    done
}
 
function makeHomeDir() {
    if [ ! -d "$CATALINA_HOME" ]; then
        echo "$CATALINA_HOME does not exist, creating"
        if [ ! -d "/var/lib/${NAME}" ]; then
            mkdir -p /var/lib/${NAME}
            cp -pLR /var/lib/tomcat5/* /var/lib/${NAME}
        fi
        mkdir -p $CATALINA_HOME ${CATALINA_HOME}/conf /var/cache/${NAME}/temp \
            /var/cache/${NAME}/work /var/log/${NAME}
        for i in temp work; do
            ln -fs /var/cache/${NAME}/${i} ${CATALINA_HOME}/${i}
        done
        for i in common server shared webapps; do
            ln -fs /var/lib/${NAME}/${i} ${CATALINA_HOME}/${i}
        done
        ln -fs /var/log/${NAME} ${CATALINA_HOME}/logs
        cp -pLR /etc/tomcat5/* ${CATALINA_HOME}/conf/
        cp -pLR /usr/share/tomcat5/bin $CATALINA_HOME
        cp -pLR /var/cache/tomcat5/work/* ${CATALINA_HOME}/work/
        chown ${TOMCAT_USER}:${TOMCAT_USER} /var/log/${NAME}
    fi
}
 
# Tachtler
function makeLogFile() {
    if [ ! -e "${TOMCAT_LOG}" ]; then
        echo "${TOMCAT_LOG} does not exist, creating"
        touch ${TOMCAT_LOG}
        chown ${TOMCAT_USER}:${TOMCAT_USER} ${TOMCAT_LOG}
    fi
}
 
function parseOptions() {
    options=""
    options="$options $(
                 awk '!/^#/ && !/^$/ { ORS=" "; print "export ", $0, ";" }' \
                 $TOMCAT_CFG
             )"
    if [ -r "/etc/sysconfig/${NAME}" ]; then
        options="$options $(
                     awk '!/^#/ && !/^$/ { ORS=" ";
                                           print "export ", $0, ";" }' \
                     /etc/sysconfig/${NAME}
                 )"
    fi
    TOMCAT_SCRIPT="$options $TOMCAT_SCRIPT"
}
 
# See how we were called.
function start() {
    echo -n "Starting ${TOMCAT_PROG}: "
    if [ -f "/var/lock/subsys/${NAME}" ] ; then
        if [ -f "/var/run/${NAME}.pid" ]; then
            read kpid < /var/run/${NAME}.pid
                if checkpid $kpid 2>&1; then
                    echo "$NAME process already running"
                        return -1
                    else
                        echo "lock file found but no process running for"
                        echo "pid $kpid, continuing"
                fi
        fi
    fi
    export CATALINA_PID="/var/run/${NAME}.pid"
    touch $CATALINA_PID
    chown ${TOMCAT_USER}:${TOMCAT_USER} $CATALINA_PID
    # Tachtler - run
    # Create a log file catalina.log if it doesn't exist
    makeLogFile
    # Tachtler - end
    if [ "$CATALINA_HOME" != "/usr/share/tomcat5" ]; then
        # Create a tomcat directory if it doesn't exist
        makeHomeDir
        # If CATALINA_HOME doesn't exist modify port number so that
        # multiple instances don't interfere with each other
        findFreePorts
        # Tachtler
        # default: sed -i -e "s/8005/${randomPort1}/g" -e "s/8080/${CONNECTOR_PORT}/g" \
        sed -i -e "s/8005/${randomPort1}/g" -e "s/8000/${CONNECTOR_PORT}/g" \
            -e "s/8009/${randomPort2}/g" -e "s/8443/${randomPort3}/g" \
            ${CATALINA_HOME}/conf/server.xml
    fi
    $TOMCAT_RELINK_SCRIPT
    $SU - $TOMCAT_USER -c "$TOMCAT_SCRIPT start" >> $TOMCAT_LOG 2>&1
    RETVAL="$?"
    if [ "$RETVAL" -eq 0 ]; then
        echo_success
        touch /var/lock/subsys/${NAME}
    else
        echo_failure
    fi
    echo
    return $RETVAL
}
 
function status() {
    RETVAL="1"
    if [ -f "/var/run/${NAME}.pid" ]; then
        read kpid < /var/run/${NAME}.pid
        if checkpid $kpid 2>&1; then
            echo "$0 is already running (${kpid})"
            RETVAL="0"
        else
            echo "lock file found but no process running for pid $kpid"
        fi
    else
        pid="$(pgrep -u tomcat java)"
        if [ -n "$pid" ]; then
            echo "$0 running (${pid}) but no PID file exists"
            RETVAL="0"
        else
            echo "$0 is stopped"
        fi
    fi
    return $RETVAL
}
 
function stop() {
    local STOP_VERBOSE="false"
    echo -n "Stopping $TOMCAT_PROG: "
    if [ -f "/var/lock/subsys/${NAME}" ]; then
        $SU - $TOMCAT_USER -c "$TOMCAT_SCRIPT stop" >> $TOMCAT_LOG 2>&1
        RETVAL="$?"
        if [ "$RETVAL" -eq "0" ]; then
            count="0"
            if [ -f "/var/run/${NAME}.pid" ]; then
                read kpid < /var/run/${NAME}.pid
                until [ "$(ps --pid $kpid | grep -c $kpid)" -eq "0" ] || \
                      [ "$count" -gt "$SHUTDOWN_WAIT" ]; do
                    if [ "$STOP_VERBOSE" = "true" ]; then
                        echo -n -e "\nwaiting for processes $kpid to exit"
                    fi
                    sleep 1
                    let count="${count}+1"
                done
                if [ "$count" -gt "$SHUTDOWN_WAIT" ]; then
                    if [ "$STOP_VERBOSE" = "true" ]; then
                        echo -n -e "\nkilling processes which didn't stop"
                        echo -n -e "after "
                        echo -n "$SHUTDOWN_WAIT seconds"
                    fi
                    kill -9 $kpid
                fi
                echo_success
                if [ "$count" -gt "0" ]; then
                    echo -n -e "\n"
                fi
            fi
            rm -f /var/lock/subsys/$NAME /var/run/$NAME.pid
        else
            echo_failure
        fi
    fi
}
 
 
# See how we were called.
case "$1" in
    start)
        parseOptions
        start
        ;;
    stop)
        parseOptions
        stop
        ;;
    restart)
        parseOptions
        stop
        sleep 2
        start
        ;;
    condrestart)
        if [ -f "/var/run/${NAME}.pid" ]; then
            parseOptions
            stop
            start
        fi
        ;;
    status)
        status
        ;;
    version)
        parseOptions
        "${JAVA_HOME}/bin/java" \
            -classpath "${CATALINA_HOME}/server/lib/catalina.jar" \
            org.apache.catalina.util.ServerInfo
        ;;
    *)
        echo "Usage: $TOMCAT_PROG {start|stop|restart|condrestart|status|version}"
        exit 1
esac
 
exit $RETVAL

/etc/tomcat5/tomcat5.conf

Die Änderungen betreffen den Standard-Port 8080 welcher auf 8000 abgeändert wurde. Dies hat wie schon erwähnt keine tiefere Bedeutung und soll nur die Möglichkeit einer solchen Änderung demonstrieren!

Es gibt auch noch einige kosmetische Anpassungen (welche vernachlässigt werden könnten).

Die relevanten Änderungen diesbezüglich sind mit einem Kommentar

# Tachtler

versehen.

# tomcat5 service configuration file
 
# you could also override JAVA_HOME here
# Where your java installation lives
JAVA_HOME="/usr/lib/jvm/java"
 
# Where your tomcat installation lives
# That change from previous RPM where TOMCAT_HOME
# used to be /var/tomcat.
# Now /var/tomcat will be the base for webapps only
CATALINA_HOME="/usr/share/tomcat5"
JASPER_HOME="/usr/share/tomcat5"
CATALINA_TMPDIR="/usr/share/tomcat5/temp"
JAVA_ENDORSED_DIRS="/usr/share/tomcat5/common/endorsed"
 
# You can pass some parameters to java
# here if you wish to
#JAVA_OPTS="-Xminf0.1 -Xmaxf0.3"
 
# Use JAVA_OPTS to set java.library.path for libtcnative.so
# Tachtler
# default: #JAVA_OPTS="-Djava.library.path=/usr/lib"
JAVA_OPTS="-Djava.library.path=/usr/lib"
 
# Bug 190:
# https://www.jpackage.org/bugzilla/show_bug.cgi?id=190
# System property catalina.ext.dirs should be set to its default value
# for ExtensionValidator to be functional.
JAVA_OPTS="$JAVA_OPTS -Dcatalina.ext.dirs=$CATALINA_HOME/shared/lib:$CATALINA_HOME/common/lib"
 
# What user should run tomcat
TOMCAT_USER="tomcat"
 
# You can change your tomcat locale here
#LANG=en_US
 
# Time to wait in seconds, before killing process
SHUTDOWN_WAIT=30
 
# Set the TOMCAT_PID location
CATALINA_PID=/var/run/tomcat5.pid
 
# Connector port is 8080 for this tomcat5 instance
# Tachtler
# default: CONNECTOR_PORT=8080
CONNECTOR_PORT=8000
 
# If you wish to further customize your tomcat environment,
# put your own definitions here
# (i.e. LD_LIBRARY_PATH for some jdbc drivers)
# Just do not forget to export them :)

/etc/tomcat5/server.xml

Die Änderungen betreffen den Standard-Port 8080 welcher auf 8000 abgeändert wurde. Dies hat wie schon erwähnt keine tiefere Bedeutung und soll nur die Möglichkeit einer solchen Änderung demonstrieren!

:!: WICHTIG Der Apache Tomcat horcht nur auf die IP-Adress 127.0.0.1.

Die relevanten Änderungen diesbezüglich sind mit einem Kommentar

<!-- Tachtler -->

versehen.

<!-- Example Server Configuration File -->
<!-- Note that component elements are nested corresponding to their
     parent-child relationships with each other -->
 
<!-- A "Server" is a singleton element that represents the entire JVM,
     which may contain one or more "Service" instances.  The Server
     listens for a shutdown command on the indicated port.
 
     Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" or "Loggers" at this level.
 -->
 
<!-- Tachtler -->
<!-- default: <Server port="8005" shutdown="SHUTDOWN"> -->
<Server port="8005" shutdown="SHUTDOWN" address="127.0.0.1">
 
  <!-- Comment these entries out to disable JMX MBeans support used for the
       administration web application -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" />
  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
 
  <!-- Global JNDI resources -->
  <GlobalNamingResources>
 
    <!-- Test entry for demonstration purposes -->
    <Environment name="simpleValue" type="java.lang.Integer" value="30"/>
 
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users -->
    <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="conf/tomcat-users.xml" />
 
  </GlobalNamingResources>
 
  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" (and therefore the web applications visible
       within that Container).  Normally, that Container is an "Engine",
       but this is not required.
 
       Note:  A "Service" is not itself a "Container", so you may not
       define subcomponents such as "Valves" or "Loggers" at this level.
   -->
 
  <!-- Define the Tomcat Stand-Alone Service -->
  <Service name="Catalina">
 
    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned.  Each Connector passes requests on to the
         associated "Container" (normally an Engine) for processing.
 
         By default, a non-SSL HTTP/1.1 Connector is established on port 8080.
         You can also enable an SSL HTTP/1.1 Connector on port 8443 by
         following the instructions below and uncommenting the second Connector
         entry.  SSL support requires the following steps (see the SSL Config
         HOWTO in the Tomcat 5 documentation bundle for more detailed
         instructions):
         * If your JDK version 1.3 or prior, download and install JSSE 1.0.2 or
           later, and put the JAR files into "$JAVA_HOME/jre/lib/ext".
         * Execute:
             %JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA (Windows)
             $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA  (Unix)
           with a password value of "changeit" for both the certificate and
           the keystore itself.
 
         By default, DNS lookups are enabled when a web application calls
         request.getRemoteHost().  This can have an adverse impact on
         performance, so you can disable it by setting the
         "enableLookups" attribute to "false".  When DNS lookups are disabled,
         request.getRemoteHost() will return the String version of the
         IP address of the remote client.
    -->
 
    <!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
    <!-- Tachtler -->
    <!-- default: <Connector port="8080" maxHttpHeaderSize="8192"
                             maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
                             enableLookups="false" redirectPort="8443" acceptCount="100"
                             connectionTimeout="20000" disableUploadTimeout="true" />
    -->
    <Connector port="8000" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="100"
               connectionTimeout="20000" disableUploadTimeout="true"
               antiJARLocking="true" address="127.0.0.1" />
    <!-- Note : To disable connection timeouts, set connectionTimeout value
     to 0 -->
 
        <!-- Note : To use gzip compression you could set the following properties :
 
                           compression="on"
                           compressionMinSize="2048"
                           noCompressionUserAgents="gozilla, traviata"
                           compressableMimeType="text/html,text/xml"
        -->
 
    <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
    <!--
    <Connector port="8443" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    -->
 
    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <!-- Tachtler -->
    <!-- default: <Connector port="8009"
               enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
    -->
    <Connector port="8009"
               enableLookups="false" redirectPort="8443" protocol="AJP/1.3"
               address="127.0.0.1" />
 
    <!-- Define a Proxied HTTP/1.1 Connector on port 8082 -->
    <!-- See proxy documentation for more information about using this. -->
    <!--
    <Connector port="8082"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" acceptCount="100" connectionTimeout="20000"
               proxyPort="80" disableUploadTimeout="true" />
    -->
 
    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host). -->
 
    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1">
    -->
 
    <!-- Define the top level container in our container hierarchy -->
    <Engine name="Catalina" defaultHost="localhost">
 
      <!-- The request dumper valve dumps useful debugging information about
           the request headers and cookies that were received, and the response
           headers and cookies that were sent, for all requests received by
           this instance of Tomcat.  If you care only about requests to a
           particular virtual host, or a particular application, nest this
           element inside the corresponding <Host> or <Context> entry instead.
 
           For a similar mechanism that is portable to all Servlet 2.4
           containers, check out the "RequestDumperFilter" Filter in the
           example application (the source for this filter may be found in
           "$CATALINA_HOME/webapps/examples/WEB-INF/classes/filters").
 
           Note that this Valve uses the platform's default character encoding.
           This may cause problems for developers in another encoding, e.g.
           UTF-8.  Use the RequestDumperFilter instead.
 
           Also note that enabling this Valve will write a ton of stuff to your
           logs.  They are likely to grow quite large.  This extensive log writing
           will definitely slow down your server.
 
           Request dumping is disabled by default.  Uncomment the following
           element to enable it. -->
      <!--
      <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
      -->
 
      <!-- Because this Realm is here, an instance will be shared globally -->
 
      <!-- This Realm uses the UserDatabase configured in the global JNDI
           resources under the key "UserDatabase".  Any edits
           that are performed against this UserDatabase are immediately
           available for use by the Realm.  -->
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase"/>
 
      <!-- Comment out the old realm but leave here for now in case we
           need to go back quickly -->
      <!--
      <Realm className="org.apache.catalina.realm.MemoryRealm" />
      -->
 
      <!-- Replace the above Realm with one of the following to get a Realm
           stored in a database and accessed via JDBC -->
 
      <!--
      <Realm  className="org.apache.catalina.realm.JDBCRealm"
             driverName="org.gjt.mm.mysql.Driver"
          connectionURL="jdbc:mysql://localhost/authority"
         connectionName="test" connectionPassword="test"
              userTable="users" userNameCol="user_name" userCredCol="user_pass"
          userRoleTable="user_roles" roleNameCol="role_name" />
      -->
 
      <!--
      <Realm  className="org.apache.catalina.realm.JDBCRealm"
             driverName="oracle.jdbc.driver.OracleDriver"
          connectionURL="jdbc:oracle:thin:@ntserver:1521:ORCL"
         connectionName="scott" connectionPassword="tiger"
              userTable="users" userNameCol="user_name" userCredCol="user_pass"
          userRoleTable="user_roles" roleNameCol="role_name" />
      -->
 
      <!--
      <Realm  className="org.apache.catalina.realm.JDBCRealm"
             driverName="sun.jdbc.odbc.JdbcOdbcDriver"
          connectionURL="jdbc:odbc:CATALINA"
              userTable="users" userNameCol="user_name" userCredCol="user_pass"
          userRoleTable="user_roles" roleNameCol="role_name" />
      -->
 
      <!-- Define the default virtual host
           Note: XML Schema validation will not work with Xerces 2.2.
       -->
      <Host name="localhost" appBase="webapps"
       unpackWARs="true" autoDeploy="true"
       xmlValidation="false" xmlNamespaceAware="false">
 
        <!-- Defines a cluster for this node,
             By defining this element, means that every manager will be changed.
             So when running a cluster, only make sure that you have webapps in there
             that need to be clustered and remove the other ones.
             A cluster has the following parameters:
 
             className = the fully qualified name of the cluster class
 
             clusterName = a descriptive name for your cluster, can be anything
 
             mcastAddr = the multicast address, has to be the same for all the nodes
 
             mcastPort = the multicast port, has to be the same for all the nodes
 
             mcastBindAddress = bind the multicast socket to a specific address
 
             mcastTTL = the multicast TTL if you want to limit your broadcast
 
             mcastSoTimeout = the multicast readtimeout
 
             mcastFrequency = the number of milliseconds in between sending a "I'm alive" heartbeat
 
             mcastDropTime = the number a milliseconds before a node is considered "dead" if no heartbeat is received
 
             tcpThreadCount = the number of threads to handle incoming replication requests, optimal would be the same amount of threads as nodes
 
             tcpListenAddress = the listen address (bind address) for TCP cluster request on this host,
                                in case of multiple ethernet cards.
                                auto means that address becomes
                                InetAddress.getLocalHost().getHostAddress()
 
             tcpListenPort = the tcp listen port
 
             tcpSelectorTimeout = the timeout (ms) for the Selector.select() method in case the OS
                                  has a wakup bug in java.nio. Set to 0 for no timeout
 
             printToScreen = true means that managers will also print to std.out
 
             expireSessionsOnShutdown = true means that
 
             useDirtyFlag = true means that we only replicate a session after setAttribute,removeAttribute has been called.
                            false means to replicate the session after each request.
                            false means that replication would work for the following piece of code: (only for SimpleTcpReplicationManager)
                            <%
                            HashMap map = (HashMap)session.getAttribute("map");
                            map.put("key","value");
                            %>
             replicationMode = can be either 'pooled', 'synchronous' or 'asynchronous'.
                               * Pooled means that the replication happens using several sockets in a synchronous way. Ie, the data gets replicated, then the request return. This is the same as the 'synchronous' setting except it uses a pool of sockets, hence it is multithreaded. This is the fastest and safest configuration. To use this, also increase the nr of tcp threads that you have dealing with replication.
                               * Synchronous means that the thread that executes the request, is also the
                               thread the replicates the data to the other nodes, and will not return until all
                               nodes have received the information.
                               * Asynchronous means that there is a specific 'sender' thread for each cluster node,
                               so the request thread will queue the replication request into a "smart" queue,
                               and then return to the client.
                               The "smart" queue is a queue where when a session is added to the queue, and the same session
                               already exists in the queue from a previous request, that session will be replaced
                               in the queue instead of replicating two requests. This almost never happens, unless there is a
                               large network delay.
        -->
 
        <!--
            When configuring for clustering, you also add in a valve to catch all the requests
            coming in, at the end of the request, the session may or may not be replicated.
            A session is replicated if and only if all the conditions are met:
            1. useDirtyFlag is true or setAttribute or removeAttribute has been called AND
            2. a session exists (has been created)
            3. the request is not trapped by the "filter" attribute
 
            The filter attribute is to filter out requests that could not modify the session,
            hence we don't replicate the session after the end of this request.
            The filter is negative, ie, anything you put in the filter, you mean to filter out,
            ie, no replication will be done on requests that match one of the filters.
            The filter attribute is delimited by ;, so you can't escape out ; even if you wanted to.
 
            filter=".*\.gif;.*\.js;" means that we will not replicate the session after requests with the URI
            ending with .gif and .js are intercepted.
 
            The deployer element can be used to deploy apps cluster wide.
            Currently the deployment only deploys/undeploys to working members in the cluster
            so no WARs are copied upons startup of a broken node.
            The deployer watches a directory (watchDir) for WAR files when watchEnabled="true"
            When a new war file is added the war gets deployed to the local instance,
            and then deployed to the other instances in the cluster.
            When a war file is deleted from the watchDir the war is undeployed locally
            and cluster wide
        -->
 
        <!--
        <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
                 managerClassName="org.apache.catalina.cluster.session.DeltaManager"
                 expireSessionsOnShutdown="false"
                 useDirtyFlag="true"
                 notifyListenersOnReplication="true">
 
            <Membership
                className="org.apache.catalina.cluster.mcast.McastService"
                mcastAddr="228.0.0.4"
                mcastPort="45564"
                mcastFrequency="500"
                mcastDropTime="3000"/>
 
            <Receiver
                className="org.apache.catalina.cluster.tcp.ReplicationListener"
                tcpListenAddress="auto"
                tcpListenPort="4001"
                tcpSelectorTimeout="100"
                tcpThreadCount="6"/>
 
            <Sender
                className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
                replicationMode="pooled"
                ackTimeout="15000"
                waitForAck="true"/>
 
            <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
                   filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
 
            <Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
                      tempDir="/tmp/war-temp/"
                      deployDir="/tmp/war-deploy/"
                      watchDir="/tmp/war-listen/"
                      watchEnabled="false"/>
 
            <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
        </Cluster>
        -->
 
 
 
        <!-- Normally, users must authenticate themselves to each web app
             individually.  Uncomment the following entry if you would like
             a user to be authenticated the first time they encounter a
             resource protected by a security constraint, and then have that
             user identity maintained across *all* web applications contained
             in this virtual host. -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->
 
        <!-- Access log processes all requests for this virtual host.  By
             default, log files are created in the "logs" directory relative to
             $CATALINA_HOME.  If you wish, you can specify a different
             directory with the "directory" attribute.  Specify either a relative
             (to $CATALINA_HOME) or absolute path to the desired directory.
        -->
        <!--
        <Valve className="org.apache.catalina.valves.AccessLogValve"
                 directory="logs"  prefix="localhost_access_log." suffix=".txt"
                 pattern="common" resolveHosts="false"/>
        -->
 
        <!-- Access log processes all requests for this virtual host.  By
             default, log files are created in the "logs" directory relative to
             $CATALINA_HOME.  If you wish, you can specify a different
             directory with the "directory" attribute.  Specify either a relative
             (to $CATALINA_HOME) or absolute path to the desired directory.
             This access log implementation is optimized for maximum performance,
             but is hardcoded to support only the "common" and "combined" patterns.
        -->
        <!--
        <Valve className="org.apache.catalina.valves.FastCommonAccessLogValve"
                 directory="logs"  prefix="localhost_access_log." suffix=".txt"
                 pattern="common" resolveHosts="false"/>
        -->
 
      </Host>
 
    </Engine>
 
  </Service>
 
</Server>

Zugriffs-Log aktivieren

Um ein Zugriffs-Log zu aktivieren sind nachfolgende Zeilen in der /usr/share/tomcat5/conf/server.xml notwendig (nur relevanter Ausschnitt):

...
        <Valve className="org.apache.catalina.valves.AccessLogValve"
                 directory="logs"  prefix="localhost_access_log." suffix=".txt"
                 pattern="common" resolveHosts="false"/>
        -->
        <!-- Tachtler -->
        <Valve className="org.apache.catalina.valves.AccessLogValve"
               directory="${catalina.base}/logs"
                  prefix="localhost_access_log."
                  suffix=".txt"
                 pattern="%h %l %u &quot;%t&quot; &quot;%r&quot; %s %b %D %S"
             resolveHost="false"
        />
...

Die Ausgabe erfolgt hier in der LOG-Datei /var/log/tomcat/localhost_access_log.2010-07-14.txt und sieht in etwa wie folgt aus:

79.228.208.100 - - [14/Jul/2010:10:16:40 +0200] "GET /index.jsp HTTP/1.1" 200 574
79.228.208.100 - - [14/Jul/2010:10:16:40 +0200] "GET /start.do HTTP/1.1" 200 21787

/etc/tomcat5/tomcat-users.xml

Um die tomcat5-admin-webapps.i386 erfolgreich betreiben zu können, ist die Anmeldung als admin bzw. und manager erforderlich. Da in der Konfiguratiosndatei /etc/tomcat5/tomcat-users.xml aber weder eine Rolle admin noch eine Rolle manager enthalten ist, muss die Originalkonfiguration wie nachfolgend dargestellt:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="role1" password="tomcat" roles="role1"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
</tomcat-users>

folgendermaßen angepasst werden:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="manager"/>
  <role rolename="tomcat"/>
  <role rolename="admin"/>
  <role rolename="role1"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
  <user username="admin" password="geheim" roles="admin,manager"/>
  <user username="role1" password="tomcat" roles="role1"/>
</tomcat-users>

Mit nachfolgendem Befehl, kann ein password= auch verschlüsselt werden. Das dazu benötigte Script bringt der Apache Tomcat leider erst ab Version 6 mit und befindet sich im bin-Verzeichnis des Apache Tomcat.

Der Aufruf des Befehls ist wie folgt zu realisieren:

# <Pfad zu Tomcat-Installation>/bin/digest.sh -a SHA geheim
geheim:906072001efddf3e11e6d2b5782f4777fe038739

Anschließend könnte die Konfigurationsdatei /etc/tomcat5/tomcat-users.xml auch wie nachfolgend dargestellt aussehen:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="manager"/>
  <role rolename="tomcat"/>
  <role rolename="admin"/>
  <role rolename="role1"/>
  <user username="tomcat" password="536c0b339345616c1b33caf454454d8b8a190d6c" roles="tomcat"/>
  <user username="both" password="536c0b339345616c1b33caf454454d8b8a190d6c" roles="tomcat,role1"/>
  <user username="admin" password="906072001efddf3e11e6d2b5782f4777fe038739" roles="admin,manager"/>
  <user username="role1" password="536c0b339345616c1b33caf454454d8b8a190d6c" roles="role1"/>
</tomcat-users>

Starten des Apache Tomcat

Um den Apache Tomcat zu starten kann folgender Befehl angewandt werden:

# service tomcat5 start
Starting tomcat5:                                          [  OK  ]

Um den Apache Tomcat zu stoppen kann folgender Befehl angewandt werden:

# service tomcat5 stop
Stopping tomcat5:                                          [  OK  ]

Eine Überprüfung ob der Start des Apache Tomcat erfolgreich war kann mit folgendem Befehl durchgeführt werden, welcher nachfolgende Ausgabe erzeugen sollte:

# netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       User       Inode      PID/Program name             
tcp        0      0 127.0.0.1:8000              0.0.0.0:*                   LISTEN      91         196641     13651/java
tcp        0      0 127.0.0.1:8005              0.0.0.0:*                   LISTEN      91         196650     13651/java
tcp        0      0 0.0.0.0:8009                0.0.0.0:*                   LISTEN      91         196646     13651/java

Die Ausgabe in der Log-Datei, hier /var/log/tomcat5/catalina.log sollte folgendermaßen aussehen:

Using CATALINA_BASE:   /usr/share/tomcat5
Using CATALINA_HOME:   /usr/share/tomcat5
Using CATALINA_TMPDIR: /usr/share/tomcat5/temp
Using JRE_HOME:
Oct 20, 2008 11:42:24 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/java/jdk1.6.0_06/jre/lib/i386/client:/usr/java/jdk1.6.0_06/jre/lib
/i386:/usr/java/jdk1.6.0_06/jre/../lib/i386:/usr/java/packages/lib/i386:/lib:/usr/lib
Oct 20, 2008 11:42:25 PM org.apache.coyote.http11.Http11BaseProtocol init
INFO: Initializing Coyote HTTP/1.1 on http-127.0.0.1-8000
Oct 20, 2008 11:42:25 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1994 ms
Oct 20, 2008 11:42:25 PM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Oct 20, 2008 11:42:25 PM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/5.5.23
Oct 20, 2008 11:42:25 PM org.apache.catalina.core.StandardHost start
INFO: XML validation disabled
Oct 20, 2008 11:42:27 PM org.apache.catalina.core.ApplicationContext log
INFO: org.apache.webapp.balancer.BalancerFilter: init(): ruleChain: [org.apache.webapp.balancer.RuleChain: [org.apache.webapp.balancer.rules.URLStringMatchRule: Target string: News / Redirect URL: http://www.cn
n.com], [org.apache.webapp.balancer.rules.RequestParameterRule: Target param name: paramName / Target param value: paramValue / Redirect URL: http://www.yahoo.com], [org.apache.webapp.balancer.rules.AcceptEvery
thingRule: Redirect URL: http://jakarta.apache.org]]
Oct 20, 2008 11:42:27 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Oct 20, 2008 11:42:27 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
Oct 20, 2008 11:42:27 PM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Oct 20, 2008 11:42:27 PM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
Oct 20, 2008 11:42:28 PM org.apache.coyote.http11.Http11BaseProtocol start
INFO: Starting Coyote HTTP/1.1 on http-127.0.0.1-8000
Oct 20, 2008 11:42:28 PM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Oct 20, 2008 11:42:28 PM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/56  config=null
Oct 20, 2008 11:42:28 PM org.apache.catalina.storeconfig.StoreLoader load
INFO: Find registry server-registry.xml at classpath resource
Oct 20, 2008 11:42:29 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 3886 ms

Um den Apache Tomcat dauerhaft bei jedem Neustart des Rechners automatisch zu starten geben Sie bitte als root folgenden Befehl ein, um zu überprüfen wie die aktuelle Konfiguration des Startverhaltens des aktuellen tomcat5-Daemons aussieht:

chkconfig --list | grep tomcat5
squid           0:off   1:off   2:off   3:off   4:off   5:off   6:off

Falls die Ausgabe wie oben gezeigt erscheinen sollte, wird der tomcat5-Daemon nicht bei jedem Neustart des Rechners gestartet. Um dies zu ändern geben Sie bitte folgende Befehle ein:

# chkconfig tomcat5 on

* Aktivieren des automatischen Startens des tomcat5-Daemons.

Das erneute Eingeben des Befehls zur Überprüfung, wie die aktuelle Konfiguration des Startverhaltens des tomcat5-Daemons aussieht, sollte dann wie folgt erscheinen:

# chkconfig --list | grep tomcat5
squid           0:off   1:off   2:on    3:on    4:on    5:on    6:off

Ergänzung: JRE_HOME

Beim aktuellen Starten des Apache Tomcat und genauerer Betrachtung der /var/log/tomcat5/catalina.out fällt auf, dass die Umgebungsvariable JRE_HOME nicht gesetzt wurde. (Auszug aus der Log-Datei /var/log/tomcat5/catalina.out):

Using CATALINA_BASE:   /usr/share/tomcat5
Using CATALINA_HOME:   /usr/share/tomcat5
Using CATALINA_TMPDIR: /usr/share/tomcat5/temp
Using JRE_HOME:
...

Ab hier werden root-Rechte zur Ausführung der nachfolgenden Befehle benötigt. Um root zu werden geben Sie bitte folgenden Befehl ein:

$ su -
Password: 

Um die Umgebungsvariable JRE_HOME zu ergänzen, müssen zwei neue Konfigurationsdateien im Verzeichnis /etc/profile.d erstellt werden. Um in das Verzeichnis /etc/profile.d zu wechseln wird folgender Befehl ausgeführt:

# cd /etc/profile.d

Die beiden neuen Konfigurationsdateien heißen:

  • /etc/profile.d/java.csh
  • /etc/profile.d/java.sh

Um die Konfigurationsdatei /etc/profiles.d/java.csh anzulegen, wird folgender Befehl ausgeführt:

# touch /etc/profile.d/java.csh

Der Inhalt sollte wie folgt aussehen:

# Make JAVA_HOME and JRE_HOME be defined for everyone
setenv JAVA_HOME /usr/java/default
setenv JRE_HOME $JAVA_HOME/jre
setenv PATH $JAVA_HOME/bin:$JRE_HOME/bin:$PATH

Ebenso um die Konfigurationsdatei /etc/profiles.d/java.sh anzulegen, wird folgender Befehl ausgeführt:

# touch /etc/profile.d/java.sh

Der Inhalt sollte wie folgt aussehen:

# Make JAVA_HOME and JRE_HOME be defined for everyone
export JAVA_HOME=/usr/java/default
export JRE_HOME=$JAVA_HOME/jre
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

Abschließend müssen beide Konfigurationsdateien noch das Dateirecht „ausführbar“ erhalten, was mit folgendem Befehl durchgeführt werden kann:

# chmod 755 /etc/profile.d/java*

:!: Ein Neustart ist nun erforderlich!

Ein Neustart kann mit folgendem Befehl durchgeführt werden:

# service tomcat5 restart
Stopping tomcat5:                                          [  OK  ]
Starting tomcat5:                                          [  OK  ]

Um zu sehen ob alles ordnungsgemäß ausgeführt wurde, können folgende Befehle genutzt werden, welche eine Ausgabe wie folgende erzeugen sollten:

# set | grep _HOME
JAVA_HOME=/usr/java/default
JRE_HOME=/usr/java/default/jre

und

# set | grep PATH
PATH=/usr/java/default/bin:/usr/java/default/jre/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

Beim erneuten Starten des Apache Tomcat und erneuter Betrachtung der /var/log/tomcat5/catalina.out fällt auf, dass die Umgebungsvariable JRE_HOME jetzt gesetzt wurde. (Auszug aus der Log-Datei /var/log/tomcat5/catalina.out):

Using CATALINA_BASE:   /usr/share/tomcat5
Using CATALINA_HOME:   /usr/share/tomcat5
Using CATALINA_TMPDIR: /usr/share/tomcat5/temp
Using JRE_HOME:       /usr/java/default/jre
...

Ergänzung: tomcat-native-lib

Beim aktuellen Starten des Apache Tomcat und erneuter genauerer Betrachtung der /var/log/tomcat5/catalina.out fällt auf, dass folgender Hinweis

  • The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: …

angezeigt wurde. (Auszug aus der Log-Datei /var/log/tomcat5/catalina.out):

Using CATALINA_BASE:   /usr/share/tomcat5
Using CATALINA_HOME:   /usr/share/tomcat5
Using CATALINA_TMPDIR: /usr/share/tomcat5/temp
Using JRE_HOME:       /usr/java/jdk1.6.0_06/jre
Oct 21, 2008 12:41:58 AM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/java/jdk1.6.0_06/jre/lib/i386/client:/usr/java/jdk1.6.0_06/jre/lib
/i386:/usr/java/jdk1.6.0_06/jre/../lib/i386:/usr/java/packages/lib/i386:/lib:/usr/lib
...

Um die Performance zu verbessern wäre das Vorhandensein der „The Apache Tomcat Native library“ sehr wünschenswert.

Herunterladen tomcat-native-lib

Es gibt ein RPM-Paket welches unter folgender Adresse heruntergeladen werden kann:

Installation tomcat-native-lib

Eine mögliche Installation wäre das RPM-Paket mit folgendem Befehl zu installieren, ausgehend davon, das das RPM-Paket sich im Verzeichnis /tmp befindet:

# yum localinstall --nogpgcheck /tmp/tomcat-native-1.1.15-1.el5.i386.rpm

Neustart Apache Tomcat

Durch einen Neustart des Apache Tomcat mit folgendem Befehl:

# service tomcat5 restart
Stopping tomcat5:                                          [  OK  ]
Starting tomcat5:                                          [  OK  ]

und wiederum genauerer Betrachtung der /var/log/tomcat5/catalina.out fällt auf, dass der Hinweis

  • The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: …

verschwunden ist. (Komplette Log-Datei /var/log/tomcat5/catalina.out):

Using CATALINA_BASE:   /usr/share/tomcat5
Using CATALINA_HOME:   /usr/share/tomcat5
Using CATALINA_TMPDIR: /usr/share/tomcat5/temp
Using JRE_HOME:       /usr/java/jdk1.6.0_06/jre
Oct 21, 2008 12:59:02 AM org.apache.coyote.http11.Http11AprProtocol init
INFO: Initializing Coyote HTTP/1.1 on http-127.0.0.1-8000
Oct 21, 2008 12:59:02 AM org.apache.coyote.ajp.AjpAprProtocol init
INFO: Initializing Coyote AJP/1.3 on ajp-8009
Oct 21, 2008 12:59:02 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 2020 ms
Oct 21, 2008 12:59:02 AM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Oct 21, 2008 12:59:02 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/5.5.23
Oct 21, 2008 12:59:03 AM org.apache.catalina.core.StandardHost start
INFO: XML validation disabled
Oct 21, 2008 12:59:04 AM org.apache.catalina.core.ApplicationContext log
INFO: org.apache.webapp.balancer.BalancerFilter: init(): ruleChain: [org.apache.webapp.balancer.RuleChain: [org.apache.webapp.balancer.rules.URLStringMatchRule: Target string: News / Redirect URL: http://www.cn
n.com], [org.apache.webapp.balancer.rules.RequestParameterRule: Target param name: paramName / Target param value: paramValue / Redirect URL: http://www.yahoo.com], [org.apache.webapp.balancer.rules.AcceptEvery
thingRule: Redirect URL: http://jakarta.apache.org]]
Oct 21, 2008 12:59:05 AM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Oct 21, 2008 12:59:05 AM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
Oct 21, 2008 12:59:05 AM org.apache.catalina.core.ApplicationContext log
INFO: ContextListener: contextInitialized()
Oct 21, 2008 12:59:05 AM org.apache.catalina.core.ApplicationContext log
INFO: SessionListener: contextInitialized()
Oct 21, 2008 12:59:05 AM org.apache.coyote.http11.Http11AprProtocol start
INFO: Starting Coyote HTTP/1.1 on http-127.0.0.1-8000
Oct 21, 2008 12:59:05 AM org.apache.coyote.ajp.AjpAprProtocol start
INFO: Starting Coyote AJP/1.3 on ajp-8009
Oct 21, 2008 12:59:05 AM org.apache.catalina.storeconfig.StoreLoader load
INFO: Find registry server-registry.xml at classpath resource
Oct 21, 2008 12:59:06 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 3527 ms

:!: Ebenfalls ist zu beobachten, das das Starten des Apache Tomcat nun deutlich schneller von statten geht, hier zum Vergleich:

vorher

INFO: Server startup in 8194 ms

nachher

INFO: Server startup in 3527 ms

Ergänzung: log4j

Das Apache Logging Services Project erstellt und verwaltet „Open-Source Software“ zur Generierung von LOG-Dateien für Applikationen und stellt diese unentgeltlich jedermann zur Verfügung.

Installation log4j

Ab hier werden root-Rechte zur Ausführung der nachfolgenden Befehle benötigt. Um root zu werden geben Sie bitte folgenden Befehl ein:

$ su -
Password: 

Folgende Schritte sind zur Installation von log4j notwendig.

Schritt 1

Es muss ein „Symbolischen Link“ im Verzeichnis /var/lib/tomcat5/commons/lib auf den bereits vorhandenen „Symblischen Link“ /usr/share/java/log4j.jar, welcher auf die Datei /usr/share/java/log4j-1.2.13.jar zeigt, mit folgendem Befehl erstellt werden:

# ln -s /usr/share/java/log4j.jar /var/lib/tomcat5/common/lib/log4j.jar

Zur Überprüfung ob die ordnungsgemäß funktioniert hat, geben Sie folgende beiden Befehle ein, welche nachfolgende Ausgaben erzeugen sollten:

# ll /var/lib/tomcat5/common/lib
...
lrwxrwxrwx 1 root root 25 Oct 22 09:04 log4j.jar -> /usr/share/java/log4j.jar
...
# ll /var/lib/tomcat5/common/lib/log4j.jar
lrwxrwxrwx 1 root root 25 Oct 22 09:04 /var/lib/tomcat5/common/lib/log4j.jar -> /usr/share/java/log4j.jar

Schritt 2

Es muss ein weiterer „Symbolischen Link“ im Verzeichnis /var/lib/tomcat5/commons/lib auf den bereits vorhandenen „Symblischen Link“ /usr/share/java/commons-logging.jar, welcher auf die Datei /usr/share/java/commons-logging-1.0.4.jar zeigt, mit folgendem Befehl erstellt werden:

# ln -s /usr/share/java/commons-logging.jar /var/lib/tomcat5/common/lib/commons-logging.jar

Zur Überprüfung ob auch dies ordnungsgemäß funktioniert hat, geben Sie folgende beiden Befehle ein, welche nachfolgende Ausgaben erzeugen sollten:

# ll /var/lib/tomcat5/common/lib
...
lrwxrwxrwx 1 root root 35 Oct 22 09:12 commons-logging.jar -> /usr/share/java/commons-logging.jar
...
# ll /var/lib/tomcat5/common/lib/commons-logging.jar
lrwxrwxrwx 1 root root 35 Oct 22 09:12 /var/lib/tomcat5/common/lib/commons-logging.jar -> /usr/share/java/commons-logging.jar

Schritt 3

Es muss eine Konfiguration für im Verzeichnis /var/lib/tomcat5/common/classes mit dem Namen log4j.properties mit folgendem Befehl anagelegt werden:

# touch /var/lib/tomcat5/common/classes/log4j.properties

Der Inhalt der Konfigurationsdatei könnte evtl. wie folgt aussehen:

log4j.rootLogger=INFO, Catalina 
log4j.appender.Catalina=org.apache.log4j.RollingFileAppender 
log4j.appender.Catalina.File=${catalina.home}/logs/catalina.out
log4j.appender.Catalina.layout=org.apache.log4j.PatternLayout 
log4j.appender.Catalina.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%-20C{1}] [%-20M] - %m%n

Schritt 4

:!: Ein Neustart ist nun erfordelich!

Ein Neustart kann mit folgendem Befehl durchgeführt werden:

# service tomcat5 restart
Stopping tomcat5:                                          [  OK  ]
Starting tomcat5:                                          [  OK  ]

Die Log-Datei des Apache Tomcat sollte nach einem Neustart dann wie folgt aussehen:

Using CATALINA_BASE:   /usr/share/tomcat5
Using CATALINA_HOME:   /usr/share/tomcat5
Using CATALINA_TMPDIR: /usr/share/tomcat5/temp
Using JRE_HOME:       /usr/java/jdk1.6.0_06/jre
2008-10-22 14:59:13 [INFO ] [Http11AprProtocol   ] [pause               ] - Pausing Coyote HTTP/1.1 on http-127.0.0.1-8000
2008-10-22 14:59:13 [INFO ] [AjpAprProtocol      ] [pause               ] - Pausing Coyote AJP/1.3 on ajp-8009
2008-10-22 14:59:14 [INFO ] [StandardService     ] [stop                ] - Stopping service Catalina
2008-10-22 14:59:15 [INFO ] [ApplicationContext  ] [log                 ] - SessionListener: contextDestroyed()
2008-10-22 14:59:15 [INFO ] [ApplicationContext  ] [log                 ] - ContextListener: contextDestroyed()
2008-10-22 14:59:15 [INFO ] [ApplicationContext  ] [log                 ] - SessionListener: contextDestroyed()
2008-10-22 14:59:15 [INFO ] [ApplicationContext  ] [log                 ] - ContextListener: contextDestroyed()
2008-10-22 14:59:15 [INFO ] [Http11AprProtocol   ] [destroy             ] - Stopping Coyote HTTP/1.1 on http-127.0.0.1-8000
2008-10-22 14:59:15 [INFO ] [AjpAprProtocol      ] [destroy             ] - Stopping Coyote AJP/1.3 on ajp-8009
Using CATALINA_BASE:   /usr/share/tomcat5
Using CATALINA_HOME:   /usr/share/tomcat5
Using CATALINA_TMPDIR: /usr/share/tomcat5/temp
Using JRE_HOME:       /usr/java/jdk1.6.0_06/jre
2008-10-22 14:59:24 [INFO ] [Http11AprProtocol   ] [init                ] - Initializing Coyote HTTP/1.1 on http-127.0.0.1-8000
2008-10-22 14:59:24 [INFO ] [AjpAprProtocol      ] [init                ] - Initializing Coyote AJP/1.3 on ajp-8009
2008-10-22 14:59:24 [INFO ] [Catalina            ] [load                ] - Initialization processed in 2001 ms
2008-10-22 14:59:24 [INFO ] [StandardService     ] [start               ] - Starting service Catalina
2008-10-22 14:59:24 [INFO ] [StandardEngine      ] [start               ] - Starting Servlet Engine: Apache Tomcat/5.5.23
2008-10-22 14:59:24 [INFO ] [StandardHost        ] [start               ] - XML validation disabled
2008-10-22 14:59:26 [INFO ] [ApplicationContext  ] [log                 ] - org.apache.webapp.balancer.BalancerFilter: init(): ruleChain: [org.apache.webapp.balancer.RuleChain: [org.apache.webapp.balancer.rules.URLStringMatchRule: Target string: News / Redirect URL: http://www.cnn.com], [org.apache.webapp.balancer.rules.RequestParameterRule: Target param name: paramName / Target param value: paramValue / Redirect URL: http://www.yahoo.com], [org.apache.webapp.balancer.rules.AcceptEverythingRule: Redirect URL: http://jakarta.apache.org]]
2008-10-22 14:59:26 [INFO ] [ApplicationContext  ] [log                 ] - ContextListener: contextInitialized()
2008-10-22 14:59:26 [INFO ] [ApplicationContext  ] [log                 ] - SessionListener: contextInitialized()
2008-10-22 14:59:26 [INFO ] [ApplicationContext  ] [log                 ] - ContextListener: contextInitialized()
2008-10-22 14:59:26 [INFO ] [ApplicationContext  ] [log                 ] - SessionListener: contextInitialized()
2008-10-22 14:59:27 [INFO ] [Http11AprProtocol   ] [start               ] - Starting Coyote HTTP/1.1 on http-127.0.0.1-8000
2008-10-22 14:59:27 [INFO ] [AjpAprProtocol      ] [start               ] - Starting Coyote AJP/1.3 on ajp-8009
2008-10-22 14:59:27 [INFO ] [StoreLoader         ] [load                ] - Find registry server-registry.xml at classpath resource
2008-10-22 14:59:27 [INFO ] [Catalina            ] [start               ] - Server startup in 3536 ms

Apache HTTP Webserver einbinden

Ein sehr häufige Kombination besteht aus dem Apache HTTP Webserver und dem Apache Tomcat.

Zwei der Möglichkeiten, wie so eine Verbindung zustande kommen kann, sollen im folgenden beschrieben werden. Die Möglichkeiten sind

  • mod_jk
  • mod_proxy_ajp

mod_jk

Ich persönlich bevorzuge die Möglichkeit über mod_jk. Die Gründe dafür sind historisch bedingt, da diese Art der Verbindung der beiden Server bereits vor der Möglichkeit der Nutzung des mod_proxy_ajp bestanden hat. Zum anderen sind meiner Ansicht folgende Vorteile gegeben:

  • Senden von spezifischen Anfragen an den Apache Tomcat z.B. (nur *.jsp-Seiten)
  • Logging Möglichkeiten (mod_jk.log)

Nachteile sind jedoch:

  • Aufwendigere Konfiguration
  • Keine verzeichnisspezifische Weiterleitung

Im folgenden soll die Vorschaltung des Apache HTTP Webserver vor den Apache Tomcat gezeigt werden:

Herunterladen mod_jk

Um das mod_jk nutzen zu können muss dieses nach der Installation erste einmal heruntergeladen werden. Dies kann unter folgendem Link erfolgen. Die aktuelle stabile Version ist 1.2.13

Einbinden mod_jk

Ab hier werden root-Rechte zur Ausführung der nachfolgenden Befehle benötigt. Um root zu werden geben Sie bitte folgenden Befehl ein:

$ su -
Password: 

Nach dem erfolgreichen herunterladen der Datei mit z.B. dem Namen mod_jk-1.2.23-apache-2.2.x-linux-i686.so, sollte diese noch umbenannt werden und in das Verzeichnis /etc/httpd/modules mit folgendem Befehl verschoben werden:

# mv /tmp/mod_jk-1.2.23-apache-2.2.x-linux-i686.so /etc/httpd/modules/mod_jk.so

Folgende Modifikationen sind an der Konfigurationsdatei /etc/httpd/conf/httpd.conf durchzuführen:

Schritt 1

Laden des Modules:

LoadModule jk_module modules/mod_jk.so

Schritt 2

Konfiguration des Modules:

<IfModule mod_jk.c>
    # Apache httpd and Apache Tomcat Connector Configuration.
    # JkRequestLogFormat: %r %q - not used, because form-field e.g. password
    #                             are shown.
    JkShmSize 64k
    JkShmFile "/var/cache/tomcat5/temp/mod_jk.shm"
 
    JkLogFile "/var/log/httpd/mod_jk.log"
    JkLogLevel error
    JkLogStampFormat "[%a, %d.%m.%Y %H:%M:%S] "
    JkRequestLogFormat "%w %R %V %v %s %b %B %U %p %T %H %m"
 
    JkWorkerProperty workers.tomcat_home="/usr/share/tomcat5"
    JkWorkerProperty workers.java_home="$JAVA_HOME"
 
    JkWorkerProperty worker.list=worker1
 
    JkWorkerProperty worker.worker1.type=ajp13
    JkWorkerProperty worker.worker1.host=127.0.0.1
    JkWorkerProperty worker.worker1.port=8009
</IfModule>

* Dies ist nur eine Beispielkonfiguration. Die Bedeutung der einzelnen Befehle kann in der Dokumentation The Apache Tomcat Connector - Reference Guide detailliert nachgelesen werden

  • JkShmSize 64k

:!: nur erforderlich für balancer- und status.worker - Zusätzlicher Cache-Speicher auf der Festplatte (Shared Memeory)

  • JkShmFile „/var/cache/tomcat5/temp/mod_jk.shm“

:!: nur erforderlich für balancer- und status.worker - Datei für den zusätzlichen Cache-Speicher auf der Festplatte (Shared Memeory)

  • JkLogFile „/var/log/httpd/mod_jk.log“

Log-Datei des Modules mod_jk

  • JkLogLevel error

Loglevel der Log-Datei des Modules mod_jk - Standard ist info

  • JkLogStampFormat „[%a, %d.%m.%Y %H:%M:%S] „

Format des verwendeten Zeitstempels - siehe auch The Apache Tomcat Connector - Reference Guide

  • JkRequestLogFormat “%w %R %V %v %s %b %B %U %p %T %H %m“

Format des Log-Eintrags - siehe auch The Apache Tomcat Connector - Reference Guide

  • JkWorkerProperty workers.tomcat_home=„/usr/share/tomcat5“

Heimatverzeichnis des Apache Tomcat

  • JkWorkerProperty workers.java_home=„$JAVA_HOME“

Heimatverzeichnis der installierten Java-Version (hier global definierte Variable - z.B. /usr/java/jdk1.6.0_06)

  • JkWorkerProperty worker.worker1.type=ajp13

Protokoll-Typ des AJP-Protokolls (1.2 oder 1.3 - :!: wobei 1.3 zu verwenden ist!)

  • JkWorkerProperty worker.worker1.host=127.0.0.1

IP-Adresse des Apache Tomcat-Servers

  • JkWorkerProperty worker.worker1.port=8009

AJP-Port des Apache Tomcat-Servers

Schritt 3

Falls kein virtueller Host definiert ist, können folgende Konfigurationsangaben ebenfalls in der Datei /etc/httpd/conf/httpd.conf definiert werden. Falls ein virtuellen Host definiert wurde, könnte dieser wie folgt aussehen:

#
# tachtler.net
#
<VirtualHost *:80>
        ServerAdmin webmaster@tachtler.net
        ServerName tachtler.net
        ServerAlias www.tachtler.net
        ServerPath /
        DocumentRoot "/usr/share/tomcat5/webapps/ROOT"
        <Directory "/usr/share/tomcat5/webapps/ROOT">
                Options FollowSymLinks
                AllowOverride None
                Order allow,deny
                Allow from all
        </Directory>
 
        JkMount /*.do worker1
        JkMount /*.jsp worker1
 
        DirectoryIndex index.htm
        ErrorLog logs/homepage_error.log
        CustomLog logs/homepage_access.log combined
</VirtualHost>

:!: WICHTIG sind hier die beiden Zeilen:

        JkMount /*.jsp worker1
        JkMount /*.do worker1

Die erste Zeile, weist den Apache HTTP Webserver alle angeforderten Seiten mit der Endung .jsp an den Apache Tomcat zur Erstellung weiterzuleiten.

Die zweite Zeile, weist den Apache HTTP Webserver alle angeforderten Seiten mit der Endung .do an den Apache Tomcat zur Erstellung weiterzuleiten. Die ist z.B. bei Nutzung des Apache Struts Frameworks der Fall.

:!: Ein Neustart ist nun erforderlich!

Ein Neustart kann mit folgendem Befehl durchgeführt werden:

# service tomcat5 restart
Stopping tomcat5:                                          [  OK  ]
Starting tomcat5:                                          [  OK  ]

Beispiel

Falls Sie nun folgende einfache *.jsp-Datei in den hier angegebenen DocumentRoot „/usr/share/tomcat5/webapps/ROOT“ legen,

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
        pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>JSP-Testseite</title>
</head>
<body>
<font style="font-family: arial; font-size: 0.8em"><%=new java.util.Date()%></font>
</body>
</html>

und diese wie folgt wie hier z.B. wie folgt aufrufen:

sollte das aktuelle Datum und die aktuelle Uhrzeit wie folgt dargestellt erscheinen

Mon Oct 27 16:56:34 CET 2008

mod_proxy_ajp

Die Konfiguration des mod_proxy_ajp ist im Vergleich zum mod_jk viel einfacher und bietet auch andere Möglichkeiten. Jedoch ist ein grosser Nachteil aus meiner Sicht, dass alle Anfragen (auch *.html-Seiten) so an den Apache Tomcat weitergeleitet werden.

:!: WICHTIG Ab Version Apache HTTP Webserver 2.2.5 kann dies mit dem Befehl

ProxyPassMatch 

jedoch ebenfalls erfolgen, wurde aber von mir noch nicht getestet!

Die Konfiguration ist im Gegensatz zum mod_jk einfacher und sieht wie folgt aus:

Einbinden mod_proxy_ajp

Ab hier werden root-Rechte zur Ausführung der nachfolgenden Befehle benötigt. Um root zu werden geben Sie bitte folgenden Befehl ein:

$ su -
Password: 

Folgende Modifikationen sind an der Konfigurationsdatei /etc/httpd/conf/httpd.conf durchzuführen:

Schritt 1

Laden der Module:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

Schritt 2

Konfiguration des Modules:

Falls kein virtueller Host definiert ist, können folgende Konfigurationsangaben ebenfalls in der Datei /etc/httpd/conf/httpd.conf definiert werden. Falls ein virtuellen Host definiert wurde, könnte dieser wie folgt aussehen:

#
# tomcat.tachtler.net
#
<VirtualHost *:80>
        ServerAdmin webmaster@tachtler.net
        ServerName tomcat.tachtler.net
        ServerAlias www.tomcat.tachtler.net
        ServerPath /
        DocumentRoot "/var/www/html/tomcat"
        <Directory "/var/www/html/tomcat">
                Options None
                AllowOverride AuthConfig
                Order allow,deny
                Allow from all
        </Directory>
 
        ProxyRequests Off
 
        ProxyPass /default ajp://127.0.0.1:8009/default
        ProxyPassReverse /default ajp://127.0.0.1:8009/default
        ProxyPass /admin ajp://127.0.0.1:8009/admin
        ProxyPassReverse /admin ajp://127.0.0.1:8009/admin
        ProxyPass /balancer ajp://127.0.0.1:8009/balancer
        ProxyPassReverse /balancer ajp://127.0.0.1:8009/balancer
        ProxyPass /host-manager ajp://127.0.0.1:8009/host-manager
        ProxyPassReverse /host-manager ajp://127.0.0.1:8009/host-manager
        ProxyPass /jsp-examples ajp://127.0.0.1:8009/jsp-examples
        ProxyPassReverse /jsp-examples ajp://127.0.0.1:8009/jsp-examples
        ProxyPass /manager ajp://127.0.0.1:8009/manager
        ProxyPassReverse /manager ajp://127.0.0.1:8009/manager
        ProxyPass /servlets-examples ajp://127.0.0.1:8009/servlets-examples
        ProxyPassReverse /servlets-examples ajp://127.0.0.1:8009/servlets-examples
        ProxyPass /tomcat-docs ajp://127.0.0.1:8009/tomcat-docs
        ProxyPassReverse /tomcat-docs ajp://127.0.0.1:8009/tomcat-docs
        ProxyPass /webdav ajp://127.0.0.1:8009/webdav
        ProxyPassReverse /webdav ajp://127.0.0.1:8009/webdav
 
        DirectoryIndex index.htm
        ErrorLog logs/tomcat_error.log
        CustomLog logs/tomcat_access.log combined
</VirtualHost>

* Dies ist nur eine Beispielkonfiguration. Die Bedeutung der einzelnen Befehle kann in der Dokumentation Apache Module mod_proxy detailliert nachgelesen werden

  • ProxyRequests Off

Deaktivieren der Eigenschaft als Standard Proxy zu fungieren!

  • ProxyPass

Alles was an die Anwendung im Verzeichnis und in der URL default gerichtet wird soll an den Apache Tomcat weitergeleitet erden, gleichzeitig wird das Verzeichnis default zum Wurzelverzeichnis ROOT bei diesem Aufruf!

  • ProxyPassReverse

Dies dient der „Rückwertsauflösung“ (reverse) der gestellten Anfragen.

  • DirectoryIndex index.htm

:!: WICHTIG - Dies ist nicht unbedingt erforderlich - hier wird folgende Datei mit dem Namen index.htm zum laden des virtuellen Hosts und der Anwendung die sich hinter dem Verzeichnis default befindet benutzt!

Die Datei index.htm sieht in diesem Beispiel wie folgt aus:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta http-equiv="refresh" content="0; URL=http://www.tomcat.tachtler.net/default">
<title>Welcome to Tomcat</title>
</head>
<body>
 
</body>
</html>

LDAP Authentifizierung

Um die Benutzer, wie z.B. admin, oder manager des Apache Tomcat gegen eine LDAP-Server, hier z.B. OpenLDAP zu authentifizieren, bedarf es nachfolgende Änderungen in folgenden Konfigurationsdateien:

  • tomcat-users.xml
  • server.xml

Ab hier werden root-Rechte zur Ausführung der nachfolgenden Befehle benötigt. Um root zu werden geben Sie bitte folgenden Befehl ein:

$ su -
Password: 

tomcat-users.xml

Falls die aktuelle /etc/tomcat5/tomcat-users.xml wie folgt aussehen sollte:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="manager"/>
  <role rolename="tomcat"/>
  <role rolename="admin"/>
  <role rolename="role1"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
  <user username="admin" password="geheim" roles="admin,manager"/>
  <user username="role1" password="tomcat" roles="role1"/>
</tomcat-users>

sollte diese wieder auf die Standard-Konfiguration zurückgesetzte werden, wie nachstehend gezeigt:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="tomcat" roles="tomcat"/>
  <user username="role1" password="tomcat" roles="role1"/>
  <user username="both" password="tomcat" roles="tomcat,role1"/>
</tomcat-users>

:!: Alle hier noch enthaltenen Benutzer und Passwörter sind nicht mehr relevant, da die Konfigurationsdatei /etc/tomcat5/tomcat-users.xml nicht mehr benötigt wird!

server.xml

In der Konfigurationsdatei /etc/tomcat5/server.xml wird die Datenbasis von der eben wieder auf die Standard-Konfiguration zurückgesetzten Konfigurationsdatei /etc/tomcat5/tomcat-users.xml auf LDAP umgestellt.

:!: Dazu wird eine org.apache.catalina.realm.JNDIRealm Klasse verwendet und nicht mehr org.apache.catalina.UserDatabase.

Die relevanten Änderungen diesbezüglich sind mit einem Kommentar

<!-- Tachtler -->

versehen.

<!-- Example Server Configuration File -->
<!-- Note that component elements are nested corresponding to their
     parent-child relationships with each other -->
 
<!-- A "Server" is a singleton element that represents the entire JVM,
     which may contain one or more "Service" instances.  The Server
     listens for a shutdown command on the indicated port.
 
     Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" or "Loggers" at this level.
 -->
 
<!-- Tachtler -->
<!-- default: <Server port="8005" shutdown="SHUTDOWN"> -->
<Server port="8005" shutdown="SHUTDOWN" address="127.0.0.1">
 
  <!-- Comment these entries out to disable JMX MBeans support used for the 
       administration web application -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" />
  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>
 
  <!-- Global JNDI resources -->
  <GlobalNamingResources>
 
    <!-- Test entry for demonstration purposes -->
    <Environment name="simpleValue" type="java.lang.Integer" value="30"/>
 
    <!-- Tachtler -->
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users 
    <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="conf/tomcat-users.xml" />
    -->
 
  </GlobalNamingResources>
 
  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" (and therefore the web applications visible
       within that Container).  Normally, that Container is an "Engine",
       but this is not required.
 
       Note:  A "Service" is not itself a "Container", so you may not
       define subcomponents such as "Valves" or "Loggers" at this level.
   -->
 
  <!-- Define the Tomcat Stand-Alone Service -->
  <Service name="Catalina">
 
    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned.  Each Connector passes requests on to the
         associated "Container" (normally an Engine) for processing.
 
         By default, a non-SSL HTTP/1.1 Connector is established on port 8080.
         You can also enable an SSL HTTP/1.1 Connector on port 8443 by
         following the instructions below and uncommenting the second Connector
         entry.  SSL support requires the following steps (see the SSL Config
         HOWTO in the Tomcat 5 documentation bundle for more detailed
         instructions):
         * If your JDK version 1.3 or prior, download and install JSSE 1.0.2 or
           later, and put the JAR files into "$JAVA_HOME/jre/lib/ext".
         * Execute:
             %JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA (Windows)
             $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA  (Unix)
           with a password value of "changeit" for both the certificate and
           the keystore itself.
 
         By default, DNS lookups are enabled when a web application calls
         request.getRemoteHost().  This can have an adverse impact on
         performance, so you can disable it by setting the
         "enableLookups" attribute to "false".  When DNS lookups are disabled,
         request.getRemoteHost() will return the String version of the
         IP address of the remote client.
    -->
 
    <!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
    <!-- Tachtler -->
    <!-- default: <Connector port="8080" maxHttpHeaderSize="8192"
                             maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
                             enableLookups="false" redirectPort="8443" acceptCount="100"
                             connectionTimeout="20000" disableUploadTimeout="true" />
    -->
    <Connector port="8000" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="100"
               connectionTimeout="20000" disableUploadTimeout="true"
               antiJARLocking="true" address="127.0.0.1" />
    <!-- Note : To disable connection timeouts, set connectionTimeout value to 0 -->
 
        <!-- Note : To use gzip compression you could set the following properties :
 
                           compression="on" 
                           compressionMinSize="2048" 
                           noCompressionUserAgents="gozilla, traviata" 
                           compressableMimeType="text/html,text/xml"
        -->
 
    <!-- Define a SSL HTTP/1.1 Connector on port 8443 -->
    <!--
    <Connector port="8443" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" disableUploadTimeout="true"
               acceptCount="100" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    -->
 
    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <!-- Tachtler -->
    <!-- default: <Connector port="8009" 
               enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
    -->
    <Connector port="8009" 
               enableLookups="false" redirectPort="8443" protocol="AJP/1.3"
               address="127.0.0.1" />
 
    <!-- Define a Proxied HTTP/1.1 Connector on port 8082 -->
    <!-- See proxy documentation for more information about using this. -->
    <!--
    <Connector port="8082" 
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" acceptCount="100" connectionTimeout="20000"
               proxyPort="80" disableUploadTimeout="true" />
    -->
 
    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host). -->
 
    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1">         
    --> 
 
    <!-- Define the top level container in our container hierarchy -->
    <Engine name="Catalina" defaultHost="localhost">
 
      <!-- The request dumper valve dumps useful debugging information about
           the request headers and cookies that were received, and the response
           headers and cookies that were sent, for all requests received by
           this instance of Tomcat.  If you care only about requests to a
           particular virtual host, or a particular application, nest this
           element inside the corresponding <Host> or <Context> entry instead.
 
           For a similar mechanism that is portable to all Servlet 2.4
           containers, check out the "RequestDumperFilter" Filter in the
           example application (the source for this filter may be found in
           "$CATALINA_HOME/webapps/examples/WEB-INF/classes/filters").
 
           Note that this Valve uses the platform's default character encoding.
           This may cause problems for developers in another encoding, e.g.
           UTF-8.  Use the RequestDumperFilter instead.
 
           Also note that enabling this Valve will write a ton of stuff to your
           logs.  They are likely to grow quite large.  This extensive log writing
           will definitely slow down your server.
 
           Request dumping is disabled by default.  Uncomment the following
           element to enable it. -->
      <!--
      <Valve className="org.apache.catalina.valves.RequestDumperValve"/>
      -->
 
      <!-- Because this Realm is here, an instance will be shared globally -->
 
      <!-- This Realm uses the UserDatabase configured in the global JNDI
           resources under the key "UserDatabase".  Any edits
           that are performed against this UserDatabase are immediately
           available for use by the Realm.  -->
      <!-- Tachtler -->
      <!-- default: <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase"/>
      -->
 
      <!-- Tachtler -->
      <Realm className="org.apache.catalina.realm.JNDIRealm" 
                 debug="99"
        connectionName="cn=Ersatzbenutzer,dc=tachtler,dc=net"
    connectionPassword="geheim"
         connectionURL="ldap://ldap.tachtler.net:389"
           userPattern="uid={0},ou=People,dc=tachtler,dc=net"
              roleBase="ou=TomcatRoles,dc=tachtler,dc=net"
              roleName="cn"
            roleSearch="(uniqueMember={0})"
      />
 
      <!-- Comment out the old realm but leave here for now in case we
           need to go back quickly -->
      <!--
      <Realm className="org.apache.catalina.realm.MemoryRealm" />
      -->
 
      <!-- Replace the above Realm with one of the following to get a Realm
           stored in a database and accessed via JDBC -->
 
      <!--
      <Realm  className="org.apache.catalina.realm.JDBCRealm"
             driverName="org.gjt.mm.mysql.Driver"
          connectionURL="jdbc:mysql://localhost/authority"
         connectionName="test" connectionPassword="test"
              userTable="users" userNameCol="user_name" userCredCol="user_pass"
          userRoleTable="user_roles" roleNameCol="role_name" />
      -->
 
      <!--
      <Realm  className="org.apache.catalina.realm.JDBCRealm"
             driverName="oracle.jdbc.driver.OracleDriver"
          connectionURL="jdbc:oracle:thin:@ntserver:1521:ORCL"
         connectionName="scott" connectionPassword="tiger"
              userTable="users" userNameCol="user_name" userCredCol="user_pass"
          userRoleTable="user_roles" roleNameCol="role_name" />
      -->
 
      <!--
      <Realm  className="org.apache.catalina.realm.JDBCRealm"
             driverName="sun.jdbc.odbc.JdbcOdbcDriver"
          connectionURL="jdbc:odbc:CATALINA"
              userTable="users" userNameCol="user_name" userCredCol="user_pass"
          userRoleTable="user_roles" roleNameCol="role_name" />
      -->
 
      <!-- Define the default virtual host
           Note: XML Schema validation will not work with Xerces 2.2.
       -->
      <Host name="localhost" appBase="webapps"
       unpackWARs="true" autoDeploy="true"
       xmlValidation="false" xmlNamespaceAware="false">
 
        <!-- Defines a cluster for this node,
             By defining this element, means that every manager will be changed.
             So when running a cluster, only make sure that you have webapps in there
             that need to be clustered and remove the other ones.
             A cluster has the following parameters:
 
             className = the fully qualified name of the cluster class
 
             clusterName = a descriptive name for your cluster, can be anything
 
             mcastAddr = the multicast address, has to be the same for all the nodes
 
             mcastPort = the multicast port, has to be the same for all the nodes
 
             mcastBindAddress = bind the multicast socket to a specific address
 
             mcastTTL = the multicast TTL if you want to limit your broadcast
 
             mcastSoTimeout = the multicast readtimeout 
 
             mcastFrequency = the number of milliseconds in between sending a "I'm alive" heartbeat
 
             mcastDropTime = the number a milliseconds before a node is considered "dead" if no heartbeat is received
 
             tcpThreadCount = the number of threads to handle incoming replication requests, optimal would be the same amount of threads as nodes 
 
             tcpListenAddress = the listen address (bind address) for TCP cluster request on this host, 
                                in case of multiple ethernet cards.
                                auto means that address becomes
                                InetAddress.getLocalHost().getHostAddress()
 
             tcpListenPort = the tcp listen port
 
             tcpSelectorTimeout = the timeout (ms) for the Selector.select() method in case the OS
                                  has a wakup bug in java.nio. Set to 0 for no timeout
 
             printToScreen = true means that managers will also print to std.out
 
             expireSessionsOnShutdown = true means that 
 
             useDirtyFlag = true means that we only replicate a session after setAttribute,removeAttribute has been called.
                            false means to replicate the session after each request.
                            false means that replication would work for the following piece of code: (only for SimpleTcpReplicationManager)
                            <%
                            HashMap map = (HashMap)session.getAttribute("map");
                            map.put("key","value");
                            %>
             replicationMode = can be either 'pooled', 'synchronous' or 'asynchronous'.
                               * Pooled means that the replication happens using several sockets in a synchronous way. Ie, the data gets replicated, then the request return. This is the same as the 'synchronous' setting except it uses a pool of sockets, hence it is multithreaded. This is the fastest and safest configuration. To use this, also increase the nr of tcp threads that you have dealing with replication.
                               * Synchronous means that the thread that executes the request, is also the
                               thread the replicates the data to the other nodes, and will not return until all
                               nodes have received the information.
                               * Asynchronous means that there is a specific 'sender' thread for each cluster node,
                               so the request thread will queue the replication request into a "smart" queue,
                               and then return to the client.
                               The "smart" queue is a queue where when a session is added to the queue, and the same session
                               already exists in the queue from a previous request, that session will be replaced
                               in the queue instead of replicating two requests. This almost never happens, unless there is a 
                               large network delay.
        -->             
        <!--
            When configuring for clustering, you also add in a valve to catch all the requests
            coming in, at the end of the request, the session may or may not be replicated.
            A session is replicated if and only if all the conditions are met:
            1. useDirtyFlag is true or setAttribute or removeAttribute has been called AND
            2. a session exists (has been created)
            3. the request is not trapped by the "filter" attribute
 
            The filter attribute is to filter out requests that could not modify the session,
            hence we don't replicate the session after the end of this request.
            The filter is negative, ie, anything you put in the filter, you mean to filter out,
            ie, no replication will be done on requests that match one of the filters.
            The filter attribute is delimited by ;, so you can't escape out ; even if you wanted to.
 
            filter=".*\.gif;.*\.js;" means that we will not replicate the session after requests with the URI
            ending with .gif and .js are intercepted.
 
            The deployer element can be used to deploy apps cluster wide.
            Currently the deployment only deploys/undeploys to working members in the cluster
            so no WARs are copied upons startup of a broken node.
            The deployer watches a directory (watchDir) for WAR files when watchEnabled="true"
            When a new war file is added the war gets deployed to the local instance,
            and then deployed to the other instances in the cluster.
            When a war file is deleted from the watchDir the war is undeployed locally 
            and cluster wide
        -->
 
        <!--
        <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
                 managerClassName="org.apache.catalina.cluster.session.DeltaManager"
                 expireSessionsOnShutdown="false"
                 useDirtyFlag="true"
                 notifyListenersOnReplication="true">
 
            <Membership 
                className="org.apache.catalina.cluster.mcast.McastService"
                mcastAddr="228.0.0.4"
                mcastPort="45564"
                mcastFrequency="500"
                mcastDropTime="3000"/>
 
            <Receiver 
                className="org.apache.catalina.cluster.tcp.ReplicationListener"
                tcpListenAddress="auto"
                tcpListenPort="4001"
                tcpSelectorTimeout="100"
                tcpThreadCount="6"/>
 
            <Sender
                className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
                replicationMode="pooled"
                ackTimeout="15000"
                waitForAck="true"/>
 
            <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
                   filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/>
 
            <Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
                      tempDir="/tmp/war-temp/"
                      deployDir="/tmp/war-deploy/"
                      watchDir="/tmp/war-listen/"
                      watchEnabled="false"/>
 
            <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener"/>
        </Cluster>
        -->        
 
 
 
        <!-- Normally, users must authenticate themselves to each web app
             individually.  Uncomment the following entry if you would like
             a user to be authenticated the first time they encounter a
             resource protected by a security constraint, and then have that
             user identity maintained across *all* web applications contained
             in this virtual host. -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->
 
        <!-- Access log processes all requests for this virtual host.  By
             default, log files are created in the "logs" directory relative to
             $CATALINA_HOME.  If you wish, you can specify a different
             directory with the "directory" attribute.  Specify either a relative
             (to $CATALINA_HOME) or absolute path to the desired directory.
        -->
        <!--
        <Valve className="org.apache.catalina.valves.AccessLogValve"
                 directory="logs"  prefix="localhost_access_log." suffix=".txt"
                 pattern="common" resolveHosts="false"/>
        -->
 
        <!-- Access log processes all requests for this virtual host.  By
             default, log files are created in the "logs" directory relative to
             $CATALINA_HOME.  If you wish, you can specify a different
             directory with the "directory" attribute.  Specify either a relative
             (to $CATALINA_HOME) or absolute path to the desired directory.
             This access log implementation is optimized for maximum performance,
             but is hardcoded to support only the "common" and "combined" patterns.
        -->
        <!--
        <Valve className="org.apache.catalina.valves.FastCommonAccessLogValve"
                 directory="logs"  prefix="localhost_access_log." suffix=".txt"
                 pattern="common" resolveHosts="false"/>
        -->
 
      </Host>
 
    </Engine>
 
  </Service>
 
</Server>

Die wichtigesten Änderungen sind hier folgende:

  • Auskommentieren, oder löschen der alten Datenbasis (org.apache.catalina.UserDatabase)
    <!-- Tachtler -->
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users 
    <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="conf/tomcat-users.xml" />
    -->

und auch hier

      <!-- Tachtler -->
      <!-- default: <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
             resourceName="UserDatabase"/>
      -->
  • Einsetzen der LDAP-Abfrage, gegen einen LDAP-Server, welcher keine anonymouse binds erlaubt! (org.apache.catalina.realm.JNDIRealm)
      <!-- Tachtler -->
      <Realm className="org.apache.catalina.realm.JNDIRealm" 
                 debug="99"
        connectionName="cn=Ersatzbenutzer,dc=tachtler,dc=net"
    connectionPassword="geheim"
         connectionURL="ldap://ldap.tachtler.net:389"
           userPattern="uid={0},ou=People,dc=tachtler,dc=net"
              roleBase="ou=TomcatRoles,dc=tachtler,dc=net"
              roleName="cn"
            roleSearch="(uniqueMember={0})"
      />

Falls ein LDAP-Server zum Einsatz kommt, der anonymouse binds erlaubt, reichen auch folgende Zeilen aus:

      <!-- Tachtler -->
      <Realm className="org.apache.catalina.realm.JNDIRealm" 
                 debug="99"
         connectionURL="ldap://ldap.tachtler.net:389"
           userPattern="uid={0},ou=People,dc=tachtler,dc=net"
              roleBase="ou=TomcatRoles,dc=tachtler,dc=net"
              roleName="cn"
            roleSearch="(uniqueMember={0})"

Abschließend ist ein Neustart des Apache Tomcat mit folgendem Befehl erforderlich:

# service tomcat5 restart
Stopping tomcat5:                                          [  OK  ]
Starting tomcat5:                                          [  OK  ]

Anlage eines entsprechenden LDAP-Baumes

Als erstes wird eine

  • organizationalUnit

mit dem Namen

  • TomcatRoles

unterhalb des Wurzelverzeichnisses, hier „dc=tachtler, dc=net“ benötigt.

Anschließend werden folgende Objekte vom Typ

  • groupOfUniqueNames

dem Pfad „ou=TomcatRoles,dc=tachtler,dc=net“ hinzugefügt:

  • admin
  • manager

Abschließend werden den jeweiligen „groupOfUniqueNames“ folgende Benutzer der Objekt-Eigenschaft

  • uniqueMember

hinzugefügt:

  • admin
    • uid=klaus,ou=people,dc=tachtler,dc=net
  • manager
    • uid=klaus,ou=people,dc=tachtler,dc=net
    • uid=werauchimmer,ou=people,dc=tachtler,dc=net

:!: Somit wären für die Anwendung admin der Benutzer klaus zugelassen und für die für die Anwendung manager der Benutzer klaus und werauchimmer!

Auslösen der Authentifizierung

Dies ist nach der Standard-Installation des Apache Tomcat bereits erledigt, jedoch soll hier zur Vervollständigung kurz erwähnt sein, wie es zur Authentifizierung kommt.

Innerhalb des jeweiligen WEB-Verzeichnisses, hier z.B. der Anwendung manager welcher ausnahmsweise in

  • /usr/share/tomcat5/server/webapps

und NICHT in

  • /usr/share/tomcat5/webapps

installiert ist, gibt es ein Verzeichnis mit dem Namen

  • WEB-INF

Innerhalb diese Verzeichnisses befindet sich die Konfigurationsdatei dieser Anwendung mit dem Namen

  • web.xml

Der Inhalt dieser Konfigurationsdatei

  • /usr/share/tomcat5/server/webapps/manager/WEB-INF/web.xml

sieht wie folgt aus (Ausschnitt relevanter Teil):

...
 
  <!-- Define a Security Constraint on this Application -->
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>HTMLManger and Manager command</web-resource-name>
      <url-pattern>/jmxproxy/*</url-pattern>
      <url-pattern>/html/*</url-pattern>
      <url-pattern>/list</url-pattern>
      <url-pattern>/sessions</url-pattern>
      <url-pattern>/start</url-pattern>
      <url-pattern>/stop</url-pattern>
      <url-pattern>/install</url-pattern>
      <url-pattern>/remove</url-pattern>
      <url-pattern>/deploy</url-pattern>
      <url-pattern>/undeploy</url-pattern>
      <url-pattern>/reload</url-pattern>
      <url-pattern>/save</url-pattern>
      <url-pattern>/serverinfo</url-pattern>
      <url-pattern>/status/*</url-pattern>
      <url-pattern>/roles</url-pattern>
      <url-pattern>/resources</url-pattern>
    </web-resource-collection>
    <auth-constraint>
       <!-- NOTE:  This role is not present in the default users file -->
       <role-name>manager</role-name>
    </auth-constraint>
  </security-constraint>
 
  <!-- Define the Login Configuration for this Application -->
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>Tomcat Manager Application</realm-name>
  </login-config>
 
  <!-- Security roles referenced by this web application -->
  <security-role>
    <description>
      The role that is required to log in to the Manager Application
    </description>
    <role-name>manager</role-name>
  </security-role>
 
</web-app>

:!: Dieser Ausschnitt bewirkt die Abfrage nach dem Benutzer, welcher die Rolle manager haben muss!

Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
tachtler/apache_tomcat_5.txt · Zuletzt geändert: 2012/06/11 13:32 von klaus