-------------- Comments added by users ------
Date: Mon, 29 Jan 2001 17:49:48 +0100
From: GOMEZ Henri 
To: tomcat-user@jakarta.apache.org
Cc: Jan Labanowski 
Subject: RE: Installation logs for Tomcat 3.2.1 and Apache 1.3.14 for RedH
    at 7.0

Did you know there is build RPM for Tomcat at jakarta.apache.org ?
http://jakarta.apache.org/builds/jakarta-tomcat/release/v3.2.1/rpms/
You may add a note in your documents.
PS: mod_jk and mo_jserv are in tomcat-mod RPM ;-)
Regards
----------------------------------------------
Date: Sat, 10 Mar 2001 00:52:20 -0500 (EST)
From: Jan Labanowski 
To: aras 
Cc: Jan Labanowski 
Subject: Re: Linux Red Hat 7.0, Apache (1.3.14), Tomcat 3.2.1, mod_jk

Steve,

Thank you for your comments... I will try to answer some of these below
and add them to the file
http://www.ccl.net/cca/software/UNIX/apache/apacheRH7.0httpd/README.html

Jan


Jan K. Labanowski            |    phone: 614-292-9279,  FAX: 614-292-7168
Ohio Supercomputer Center    |    Internet: jkl@ccl.net
1224 Kinnear Rd,             |    http://www.ccl.net/chemistry.html
Columbus, OH 43212-1163      |    http://www.ccl.net/


On Fri, 9 Mar 2001, aras wrote:

>.... the intro deleted ...
>
> In step 9 you got JAXP.  Exactly what is it for?  Does TomCat use
> jaxp.jar and/or parser.jar in parsing out web.xml and server.xml?  If
> so, How is it called?

There is a lot of XML parsing in Tomcat. And beside, the ANT is used to build
Tomcat, and build files of ANT are XML files.
In jakarta-tomcat-3.2.1-src/src/j2ee/org/apache/tomcat/util/XMLParser.java the
XML validating parser from JAXP is used to parse web.xml and server.xml.
>
>
> The files you suggest for testing jaxp, in step 12, wern't in my jaxp
> dir, so I used DOMEcho.  I think it's the same stuff.
   Because in the meantime, the JAXP Early Access 1.1 became Final
   JAXP 1.1, which is different.
>
>
> In step 17 I received many errors from tomcat.sh, that complained about
> the ==.  I'm using bash.  I don't think bash has a == operator.

  man bash under CONDITIONAL EXPRESSIONS section:

       string1 == string2
              True  if  the  strings are equal.  = may be used in
              place of ==.

Are you sure you are using bash? Do you have a link in /bin
  sh -> bash


> I
> changed all the == back to a single = .  The other part I didn't
> understand was your use of the :- operator.  I thought its use was
> such:   echo $TOMCAT_HOME:-'TomCat var not defined'

Again man bash says under Parameter Expansion.

       ${parameter:-word}
              Use Default Values.  If parameter is unset or null,
              the  expansion  of word is substituted.  Otherwise,
              the value of parameter is substituted.

I like this one since it has smiley face... In this case, if
TOMCAT_HOME is defined, it expands to the content of ${TOMCAT_HOME},
and it TOMCAT_HOME is not defined, it expands to empty string, i.e., "".
The way people do it usually is:

     if [ "x${TOMCAT_HOME}" == "x" ] ; then
        do stuff when TOMCAT_HOME not set or empty
     else
        do stuff when TOMCAT_HOME is set and nonempty
     fi


> You have code like this  ${TOMCAT_HOME:-}  I don't get it.  I changed it
> to ${TOMCAT_HOME:-'blah/blah/tomcat'} I don't know if I'm right, and I
> actually thought I should use the := operator so it would set the env
> var.

You cannot set the TOMCAT_HOME (if not set) in the conditional since
you do not know. What they do is:

if [ "${TOMCAT_HOME:-}" == "" ] ; then
  # try to find tomcat
  if [ -d ${HOME}/opt/tomcat/conf ] ; then
    TOMCAT_HOME=${HOME}/opt/tomcat
    echo "Defaulting TOMCAT_HOME to $TOMCAT_HOME"
  fi
  if [ -d /opt/tomcat/conf ] ; then
    TOMCAT_HOME=/opt/tomcat
    echo "Defaulting TOMCAT_HOME to $TOMCAT_HOME"
  fi                                                                              # Add other "standard" locations for tomcat
fi

>
> In step 19 I recieved an error stating "bad user name apache"  I figured
> maybe it was in httpd.conf so I added the user apache and that seemed to
> go away.  Why the user apache?  Benefits?

Good point!!!
This is probably because you did not install RH7.0 from scratch, but
upgraded from the previous linux installation of RH, and previous
version of Linux and Apache used user/group nobody for apache.
Starting from RH7.0 the default user which runs apache is "apache"
and is included in the default /etc/passwd and /etc/group created during
installation.
apache:x:48:48:Apache:/var/www:/bin/false        (in /etc/passwd).
apache:x:48:                                     (in /etc/group).
You probably should add these entries to respective files, or change
apache to nobody in the default httpd.conf.


>
> Lastly, in step 23 you added to new users.  I'm guessing security.  You
> tried to explain the need for tcsh but I still don't understand.  I
> thought it was becasue the c files you wrote in step 26.  Is there
> someting tcsh provides that bash does not?
Yes, it is for security reason. Apache server starts as root (usually)
and then it spawns the children which run as user/group specified
in the httpd.conf file. If it was running as root serving requests,
it would be a substantial security risk. When someone gains access to
your computer through some untidy CGI script or servlet as nobody, apache,
or webrun (in my case), they cannnot do much harm. But if they were root,
they can change your password file, install trojan horses, you name it...
So the idea is to run the processes of tomcat and apache servers as
some users with very few privileges, which do not own many files (they
only need to own log files, since they have to write to them).
>
>
> Again, thanks for your time.
>
>
> Best regards,
>
> Steve
>                                                                               
---------------------------------------------------------------------------

This is a log of my installation of precompiled Apache DSO
with SSL, MM, and Tomcat 3.2.1 final (binary distribution) and EA JAXP 1.1
on RedHat Linux 7.0, Kernel 2.2.16-22, with updates up to 2000.12.31.
In this case, I am using the Apache server which came with original 
RedHat 7.0 Linux distribution rather than compiling Apache from source.
This memo was originally written around Jan 15, 2001
Few terms:

  Apache -- the Web Server
  DSO -- Dynamic Shared Object (additional modules can be added/updated
         to Apache without the need to recompile the whole thing, similar
         to shared libraries, but DSO modules are not only called, but
         can also call routines within Apache)
         
  MM  -- memory management or something like that - an add-on to Apache
         and its modules to communicate via shared memory rather than files
         (faster). 

  SSL -- Secure Socket Layer - the encryption and certificate package which
         works with Apache

  Tomcat -- the Java Server Pages (JSP) and Servlet container which uses the
         Java Servlets spec 2.2, and the JSP spec 1.1.
         It is still being actively developed and has some "features", 
         but is quite stable. People complain about mod_jk and 
         ajp13 occassionally.

You may want to read my FAQ on Tomcat 3.1 beta 1. since it will be
easier to follow this installation log. It is available at:
   http://www.ccl.net/cca/software/UNIX/apache/tomcat3.1b1-faq.html

I assume that you will use this document simply by grabbing the UNIX
commands from the browser window, and pasting them into your xterm
or whatever. The Unix commands are in italic.

I assume that you have moderately latest GNU tools (gmake, gzip, etc...)
installed and you also have a recent version of perl installed 
( http://www.cpan.org/src/index.html ). These should have come with your RH Linux
distribution. 
You can also get the wget utility from
 ftp://ftp.gnu.org/pub/gnu/wget/
and install it (it is at ver 1.6 now): 
    get wget-1.6.tar.gz and move it to directory /usr/local/uploads or
       the one you like the most, e.g.; /tmp.
    gtar zxvf wget-1.6.tar.gz
    cd wget-1.6

    ./configure
    make
    make install

and make sure it is in your PATH variable. It is usually installed in
/usr/local/bin by default. But check... Type wget alone on the
command line, and if it tells you that your URL is missing, you are OK.


Be a root... Run ksh or other sh (e.g., bash), but not C-shell.
Install all the updates available for the Linux (e.g., go to
the site: http://rpmfind.net.
I installed the following updates. You probably do not need all of them.
But it never hurts to update (I am not talking about MS updates, here...{:-)).
The ones marked bold are strongly recommended updates

rpm -Uhv LPRng-3.6.24-2.i386.rpm

rpm -Uhv apache-1.3.14-3.i386.rpm  \
         apache-devel-1.3.14-3.i386.rpm \
         apache-manual-1.3.14-3.i386.rpm \
         mod_perl-1.24-6.i386.rpm \
         mod_ssl-2.7.1-3.i386.rpm


rpm -Uhv auth_ldap-1.4.5-1.i386.rpm 

rpm -Uhv bind-8.2.2_P7-1.i386.rpm bind-devel-8.2.2_P7-1.i386.rpm \
         bind-utils-8.2.2_P7-1.i386.rpm

rpm -Uhv cpp-2.96-69.i386.rpm 

rpm -Uhv cyrus-sasl-1.5.24-11.i386.rpm cyrus-sasl-1.5.24-11.src.rpm

rpm -Uhv e2fsprogs-1.18-16.i386.rpm e2fsprogs-devel-1.18-16.i386.rpm

rpm -Uhv ed-0.2-19.i386.rpm

rpm -Uhv emacs-20.7-17.i386.rpm emacs-X11-20.7-17.i386.rpm \
    emacs-el-20.7-17.i386.rpm emacs-leim-20.7-17.i386.rpm \
    emacs-nox-20.7-17.i386.rpm

rpm -Uhv fetchmail-5.5.0-3.i386.rpm fetchmailconf-5.5.0-3.i386.rpm

rpm -Uhv gcc-2.96-69.i386.rpm gcc-c++-2.96-69.i386.rpm \
         gcc-chill-2.96-69.i386.rpm gcc-g77-2.96-69.i386.rpm \
         gcc-objc-2.96-69.i386.rpm 

rpm -Uhv ghostscript-5.50-8.i386.rpm

rpm -Uhv glibc-2.2-12.i386.rpm glibc-common-2.2-12.i386.rpm \
         glibc-devel-2.2-12.i386.rpm glibc-profile-2.2-12.i386.rpm

rpm -Uhv imap-2000-3.i386.rpm imap-devel-2000-3.i386.rpm 

rpm -Uhv iputils-20001010-1.i386.rpm

rpm -Uhv joe-2.8-43.i386.rpm

rpm -Uhv kpackage-1.3.10-7.i386.rpm

rpm -Uhv libstdc++-2.96-69.i386.rpm libstdc++-devel-2.96-69.i386.rpm

rpm -Uhv mod_dav-1.0.2-2.i386.rpm

rpm -Uhv modutils-2.3.21-1.i386.rpm

rpm -Uhv mount-2.10m-6.i386.rpm

rpm -Uhv mysql-3.23.29-1.i386.rpm mysql-devel-3.23.29-1.i386.rpm \
     mysql-server-3.23.29-1.i386.rpm

rpm -Uhv mysqlclient9-3.23.22-3.i386.rpm

rpm -Uhv ncurses-5.2-2.i386.rpm ncurses-devel-5.2-2.i386.rpm

rpm -Uhv netscape-common-4.76-1.i386.rpm \
         netscape-communicator-4.76-1.i386.rpm \
         netscape-navigator-4.76-1.i386.rpm
 
rpm -Uhv nscd-2.2-12.i386.rpm 

rpm -Uhv nss_ldap-122-1.7.i386.rpm nss_ldap-122-1.7.src.rpm

rpm -Uhv openssh-2.3.0p1-4.i386.rpm openssh-askpass-2.3.0p1-4.i386.rpm \
         openssh-askpass-gnome-2.3.0p1-4.i386.rpm \
         openssh-clients-2.3.0p1-4.i386.rpm \
         openssh-server-2.3.0p1-4.i386.rpm

rpm -Uhv pam-0.72-37.i386.rpm

rpm -Uhv pine-4.30-2.i386.rpm

rpm -Uhv python-xmlrpc-1.2.1-1.i386.rpm

rpm -Uhv rp-pppoe-2.5-1.i386.rpm rp-pppoe-2.5-1.src.rpm

rpm -Uhv slocate-2.4-1.i386.rpm

rpm -Uhv stunnel-3.10-2.i386.rpm

rpm -Uhv sysklogd-1.3.33-8.i386.rpm

rpm -Uhv sysstat-3.2.4-5.i386.rpm

rpm -Uhv tcsh-6.10-1.i386.rpm

rpm -Uhv tmpwatch-2.6.2-1.7.i386.rpm

rpm -Uhv usermode-1.37-2.i386.rpm

rpm -Uhv xinetd-2.1.8.9pre11-1.i386.rpm

After you made the updates, it is a prudent thing to actually reboot the
machine.


1) Install Java 1.3. I did: 
    a) went to http://www.javasoft.com
    b) clicked on Products and API on the left bar
    c) clicked on Java 2 platform Standard edition J2SE
    d) Java 2 SDK Standard Edition v 1.3
    e) Linux x86
    f) GNUZIP Tar shell script, one large bundle -> [continue]
    g) Yes to license [Accept]
    h) j2sdk-1_3_0-linux.bin = 26,857,036 bytes -> FTP download
    i) I placed the file j2sdk-1_3_0-linux.bin in:
         /usr/local/uploads
    j) cd  /usr/local/uploads
       chmod 755 j2sdk-1_3_0-linux.bin
       ./j2sdk-1_3_0-linux.bin
    k) this produced directory: /usr/local/uploads/jdk1.3
       I moved this directory :
          mv /usr/local/uploads/jdk1.3 /usr/local/j2sdk-1_3_0
       and then made a link:
          ln -s /usr/local/j2sdk-1_3_0 /usr/local/jdk1.3

    l) set environment variables:

        JAVA_HOME=/usr/local/jdk1.3
        export JAVA_HOME
        PATH=/usr/local/bin:${JAVA_HOME}/bin:${PATH}
        export PATH
        CLASSPATH=${JAVA_HOME}/lib/tools.jar:${JAVA_HOME}/lib/dt.jar
        export CLASSPATH

3) Installed JCE 1.2.1 Java Cryptography Extension 1.2.1 
    Go to: http://www.javasoft.com/products/jce/
    Click on: Download JCE 1.2.1 Software, policy files, and docs  
    This will get you: jce-1_2_1.zip
      mkdir /usr/local/JCE
      cd /usr/local/JCE
      cp ..../jce-1_2_1.zip .
      unzip jce-1_2_1.zip
    Then added the security provider to Java:
      a) copied JCE jars to lib/ext
         cp /usr/local/JCE/jce1.2.1/lib/*.jar /usr/local/jdk1.3/jre/lib/ext
         CLASSPATH=${CLASSPATH}:${JAVA_HOME}/jre/lib/ext/jce1_2_1.jar
         export CLASSPATH
      b) edited /usr/local/jdk1.3/jre/lib/security/java.security and added
         line: 
          security.provider.3=com.sun.crypto.provider.SunJCE

4) Installed JSSE (JavaTM Secure Socket Extension (JSSE) 1.0.2)
   available from http://java.sun.com/products/jsse/
      mkdir /usr/local/jsse
   with a browser go to: http://java.sun.com/products/jsse/
    Click on domestic distribution
    Logged in, accepted, continue, answered Yes, Continue, 
    downloaded jsse-1_0_2-do.zip  
       cd /usr/local/jsse
       cp ..../jsse-1_0_2-do.zip .
       unzip jsse-1_0_2-do.zip
    I installed the JSSE as "installed extension" for jdk1.3 and
    copied them to /usr/local/jdk1.3/jre/lib/ext directory
    ($JAVA_HOME/jre/lib/ext):

       cp -p /usr/local/jsse/jsse1.0.2/lib/*jar $JAVA_HOME/jre/lib/ext
       CLASSPATH=${CLASSPATH}:${JAVA_HOME}/jre/lib/ext/jcert.jar
       CLASSPATH=${CLASSPATH}:${JAVA_HOME}/jre/lib/ext/jnet.jar
       CLASSPATH=${CLASSPATH}:${JAVA_HOME}/jre/lib/ext/jsse.jar
       export CLASSPATH

    Then, I registered the provider in $JAVA_HOME/jre/lib/security/java.security
    by adding a line:
           security.provider.4=com.sun.net.ssl.internal.ssl.Provider   

   
5) If you have apache installed by default from the RH7.0 CD, or if you
   installed RH7.0 apache, you can skip the apache installation.
   If you installed some other Apache distribution or RPMs, you are on
   your own, since IT can be anything anywhere.
   My install was as:
      Put RH7.0 CD Nr 1 to CD DRIVE

      mount /mnt/cdrom

      cd /mnt/cdrom/RedHat/RPMS

      rpm -Uhv apache* 
      rpm -Uhv mod_ssl* mod_perl* openssl*

   If it tells you that some package is already installed, remove it from
   the line and try again (e.g., openssl will most likely be installed).
   If it tells you that it needs a package (unsolved dependancies), add
   the package to the command line and try again.


   The RH Apache distribution places the important files in:
     /usr/lib/apache              -- shared modules
     /usr/include/apache          -- include files needed for compiling modules
     /etc/httpd                   -- config and authorization files
     /usr/sbin/httpd              -- executable of httpd 
     /usr/sbin/apxs               -- executable of apxs
     /usr/bin/dbmmanage           -- to manage database of authorized users
     /var/log/httpd               -- apache log files
     /var/www/icons               -- GIFs needed by Apache 
     /var/www/html                -- document root
     /var/www/cgi-bin             -- cgi bin directory
     /usr/share/ssl               -- SSL files needed to produce certificates
  
6) While RH apache comes with the test certificate installed in the
   /etc/httpd/conf, you need to produce a new set of self-signed
   certificates/keys which have your machine name as "Common Name". Otherwise
   the browsers will complain that your certificate name does not match
   the actual name of the machine.
   My log from Certificate creation is here. What I did was:

      cd /etc/httpd/conf
      mkdir old-keys
      mv ssl* old-keys
      mkdir ssl.key
      mkdir ssl.csr
      mkdir ssl.crt
      make genkey
       # Then, you will need to "unpassword" the keys
       # or you would have problems to start apache at boot time (it would
       # ask for the password)
      openssl rsa -in ssl.key/server.key -out ssl.key/server.key.unsecure
      cp ssl.key/server.key.unsecure ssl.key/server.key
      make certreq
      make testcert

   One thing to remember, is to enter the fully qualified domain name of the
   host on which this Apache Web server runs (in my case: pse.ccl.net) as
   the "Common Name".
   I then tarred my certificates/keys into a file:

     cd /etc/httpd/conf
     tar zcvf /usr/local/apache-certificates.tgz ssl*
     chmod 600 /usr/local/apache-certificates.tgz
   
   just in case, if I lost them, I can restore original certificates,
   without forcing users to go through the Certificate registration
   process in their browser.

   You can also copy them on the diskette and keep them safely. In my case:
     fdformat /dev/fd0H1440
     mkfs -t msdos /dev/fd0H1440
   and, assuming that you have a line:
      /dev/fd0       /mnt/floppy      auto    noauto,owner    0 0
   in your /etc/fstab file, and that the directory /mnt/floppy exists,
   you mount it as:
      mount /mnt/floppy
   then copy your certificates:
      cp /usr/local/apache-certificates.tgz /mnt/floppy
   Unmount your diskette:
      umount /mnt/floppy
   and put the diskette in the safe place. 
   Of course, you could also to it with Mutils, if you have them installed:
     mformat -f 1440 a:
     mcopy /usr/local/apache-server1-certificates.tgz a:
     mdir a:

6) You start Apache with a script which comes with the RPM:
       /etc/rc.d/init.d/httpd start
   and stop it by:
       /etc/rc.d/init.d/httpd stop

   To make apache start automatically at boot time:    
    
       cd /etc/rc.d/init.d
       chkconfig --add httpd
      
   and check if the links for the rc.d* directories were added:

       chkconfig --list httpd-jkl

   which should give:
       httpd       0:off   1:off   2:off   3:on    4:on    5:on    6:off


   Stop apache, since you are not finshed yet.

       /etc/rc.d/init.d/httpd stop




        Installing binary distribution of Tomcat
        ========================================

7)  Create directory for Tomcat and set JAKARTA_HOME variable:

      mkdir /usr/local/jakarta_3.2.1
      cd /usr/local/jakarta_3.2.1
      JAKARTA_HOME=/usr/local/jakarta_3.2.1
      export JAKARTA_HOME

    Go to Jakarta site and download binary tar balls to ${JAKARTA_HOME} 
     wget http://jakarta.apache.org/builds/tomcat/release/v3.2.1/bin/jakarta-servletapi-3.2.tar.gz
     wget http://jakarta.apache.org/builds/tomcat/release/v3.2.1/bin/jakarta-tomcat-3.2.1.tar.gz

    I am including the local copies here:
       jakarta-servletapi-3.2.tar.gz
       jakarta-tomcat-3.2.1.tar.gz

    Then, I "ungnunzip-untarred" (:-)} the  tar balls:
        tar zxvf jakarta-servletapi-3.2.tar.gz   
        tar zxvf jakarta-tomcat-3.2.1.tar.gz     

8)   At this point it is probably prudent to log out and log in again as root
     and reset your environment variables by doing:
       JAVA_HOME=/usr/local/jdk1.3
       export JAVA_HOME
       PATH=/usr/local/bin:${JAVA_HOME}/bin:${PATH}
       export PATH
       CLASSPATH=${JAVA_HOME}/lib/tools.jar:${JAVA_HOME}/lib/dt.jar
       export CLASSPATH
       JAKARTA_HOME=/usr/local/jakarta_3.2.1
       export JAKARTA_HOME
       TOMCAT_HOME=${JAKARTA_HOME}/jakarta-tomcat-3.2.1
       export TOMCAT_HOME

9) You need to get the latest JAXP (Sun API and XML parsing in Java). They
   have the Early Access 1.1. Take it... It has DOM2 and SAX2, while 
   the stable JAXP 1.0 has only DOM1 and SAX1. So, go to:
       http://java.sun.com/xml/
   click on Java API for XML Processing Reference Implementation
   Java API for XML Processing Reference Implementation
   Version 1.1 Early Access 2
   Java API for XML Processing Reference Implementation version 1.1ea2
   You have to be registered (I you do Java, you are registered...)
   Agree to whatever (but be careful, since their lawyers look for work
   after they finished the settlement with MS) and click on download to get:
       jaxp-1_1-ea2.zip = 3,095,370 bytes  
   I have placed it in /tmp and then:
       cd /tmp
       unzip  jaxp-1_1-ea2.zip 
       mv  jaxp-1.1ea2 /usr/local

       XML=/usr/local/jaxp-1.1ea2
       export XML
       CLASSPATH=${CLASSPATH}:${XML}/jaxp.jar:${XML}/crimson.jar
       CLASSPATH=${CLASSPATH}:${XML}/xalan.jar
       export CLASSPATH

10) At this point it is good to create a simple shell script
    which will set your environmental variables, so when you come back
    after logout,  you do not have to type all this stuff. I placed the
    setmyenv in my /root directory
    and did:
       .  /root/setmyenv
    as the first thing after log in (of course, I could put this stuff
    in the .bashrc, but I like to start with clean root environment, so
    I know what is happening).


11) Delete the parser.jar and jaxp.jar from the ${TOMCAT_HOME}/lib

     cd ${TOMCAT_HOME}/lib
     rm jaxp.jar parser.jar
     Note, I did not put the new jars into the ${TOMCAT_HOME}/lib at this time.
     I rather have them in the CLASSPATH until things stabilize...
      
12)  I compiled and ran JAXP examples:

        cd ${XML}/examples/dom
        javac main.java
        java -cp ${CLASSPATH}:. main

        cd ${XML}/examples/sax
        javac main.java

     and did the example for invalid document:

        java -cp ${CLASSPATH}:. -Djavax.xml.parsers.validation=true \
             main ../samples/namespace.xml

     and the one for the valid document:

        java -cp ${CLASSPATH}:. -Djavax.xml.parsers.validation=true \
             main ../samples/book-order.xml

     and the one for the well-formedness only

        java -cp ${CLASSPATH}:. main ../samples/namespace.xml


     and they seemed to work. 



14) To use Tomcat with Apache, you need mod_jk or mod_jserv.
    Those are modules for Apache which allow Apache to talk to Tomcat
    servlet container via TCP socket. In this scenario, the Apache
    is handling communication with outside world (takes the HTTP requests).
    When request is for JSP page or a servlet, it passes it to Tomcat.
    To do that Apache needs a module which knows how to talk to Tomcat,
    and Tomcat has to listen to Apache on some port. Moreover, they need
    to agree, how they will talk to each other (the protocol: there are two
    of them at this moment: ajp12 and ajp13), and which TCP ports they will use
    to communicate (i.e., Apache has to know where Tomcat will be listening -
    note, tomcat does not have to be on the same machine, and there may be
    many tomcats listening to the same Apache, or many Apaches taking to the
    same Tomcat -- but this is outside the primer given here).
    I will not talk about the mod_jserv. While it is an excellent piece
    of work, it also is getting old and is now considered a legacy. It
    was originally developed for JSERV, the server engine for Servlet 2.0
    spec, which is passe (it is 2 years old, i.e., ancient and obsolete)
    but, on the other hand, it is well debugged and used for production,
    as opposed to mod_jk, but again, I like bleeding edge, but do not call
    911 yet...). So again. mod_jk is the module which plugs into Apache.
    Tomcat is a TCP server (i.e., opens a TCP port and listens to clients
    who come and want to talk to it), and Apache is a TCP client for Tomcat,
    i.e., it starts talking. The small problem for non programmers is that
    you do not get a binary mod_jk with Tomcat. You only get the source.
    You need to compile the mod_jk. It is not a big deal:

      cd ${JAKARTA_HOME}
      wget http://jakarta.apache.org/builds/tomcat/release/v3.2.1/src/jakarta-tomcat-3.2.1-src.tar.gz
      tar zxvf jakarta-tomcat-3.2.1-src.tar.gz 
      cd ${JAKARTA_HOME}/jakarta-tomcat-3.2.1-src/src/native
      cd apache1.3
      /usr/sbin/apxs -o mod_jk.so  \
        -I${JAVA_HOME}/include/linux \
        -I../jk -I${JAVA_HOME}/include \
        -c *.c ../jk/*.c
      cp mod_jk.so /usr/lib/apache

     While I provide the binary of mod_jk.so 
     here (save it as: RightClick/SaveLinkAs)
     you should really compile it on your own machine. 


15)Test tomcat standalone:
    Since there are a lot of files in the $TOMCAT_HOME/conf, I decided
    to move all files which are there to a separate directory, and then
    copy what I need back:
       cd $TOMCAT_HOME/conf
       mkdir original-conf
       mv * original-conf
       cd original-conf
       cp server.xml ..
       cp web.xml ..
       cp workers.properties ..
       cp tomcat-users.xml ..

    I looked at my ${TOMCAT_HOME}/conf/server.xml
    and added connector for protocol ajp13 at port 8006
    (you have to keep ajp12 connector, even if you do not use it, to be
    able to shut down Tomcat). I also changed all the docBases in
    Context tags to full paths, e.g.:
      docBase="webapps/examples" --> 
        docBase="/usr/local/jakarta_3.2.1/jakarta-tomcat-3.2.1/webapps/examples
     
    I also created directory (for testing) below Apache DocumentRoot

        mkdir /var/www/html/examples-test

    and unpacked there an examples.war file so I can do testing of new
    Context, which is not in a default location: ${TOMCAT_HOME}/webapps.

        cd /var/www/html/examples-test
        jar xvf ${TOMCAT_HOME}/webapps/examples.war
    
    I then mounted examples-test directory in ${TOMCAT_HOME}/conf/server.xml .
    My initial server.xml file is here.

    Note that server.xml is the file which is read in by Tomcat to
    configure itself. Tomcat does not use any information from
    workers.properties or mod_jk.conf for itself. These are meant for
    apache or other Web severs for which Tomcat works.
    There may be some confusion here, since Tomcat actually produces
    prototype configuration files for various Web servers. These files
    have the *.auto extension. The following files were produce on
    runing startup.sh: iis_redirect.reg-auto and uriworkermap.properties-auto
    (for MS IIS), mod_jk.conf-auto (for mod_jk module of Apache),
    obj.conf-auto (for Netescape or whoever/whatever server, if you know
    what I mean), and tomcat-apache.conf (for Apache mod_jserv module which
    we do not use here). These are prototype files, which are essentially
    ready to go for simple configurations. The files like tomcat-apache.conf,
    tomcat.properties, tomcat.conf are used when tomcat was working with
    mod_jserv module. We are using here mod_jk module, and these files can
    be ignored. The files for mod_jk module of Apache are mod_jk.conf
    and workers.properties. For the time being, I tested if Tomcat works
    alone by starting it as:
 
       cd ${TOMCAT_HOME}/bin
       ./startup.sh

   You should get something like here

   Then, try to see Tomcat in your browser:
        http://your.machine:8080/
   Try some examples, (http://your.machine:8080/examples/jsp), etc.
   If you think that have problems shut it down as:

        cd ${TOMCAT_HOME}/bin 
        ./shutdown.sh

   and see if ports 8080 and 8007 are not booked by something else. List
   ports as: 
      netstat -a -n | grep -i listen

   Before we worke on config files, it may be good to shutdown the
   Tomcat:
        ./shutdown.sh

16) After testing Tomcat, it created automatically a config file for
    mod_jk for Apache as $TOMCAT_HOME/conf/mod_jk.conf-auto.
    I saved this file as mod_jk.conf and edited it:
        cd $TOMCAT_HOME/conf
        mv mod_jk.conf-auto mod_jk.conf
    I edited the Apache config file,  /etc/httpd/conf/httpd.conf, to include
    the mod_jk.conf at the very end (more needs to be done for sensible
    install, though). I added a line at the end of httpd.conf
       Include /usr/local/jakarta_3.2.1/jakarta-tomcat-3.2.1/conf/mod_jk.conf
    The actual initial httpd.conf is here.

    In mod_jk.conf I replaced all occurances of ajp12 with ajp13 and made few
    other changes. You can find the copy of it here.

    I also made several changes to workers.properties. Namely:
    changed workers.tomcat_home, workers.java_home, ps, and 
    worker.ajp13.port port to 8006. Also commented out all inprocess 
    definitions (tomcat does not run inprocess within apache).
    You can look them up here.
    Note, my ajp12 port is 8007 and ajp13 is 8006.
 
17) Heavily edited the $TOMCAT_HOME/bin/startup.sh, 
    $TOMCAT_HOME/bin/startup.sh and $TOMCAT_HOME/bin/jspc.sh and
    also tomcat.sh (made it write a pid file in $TOMCAT_HOME/logs/tomcat.pid
    so it can be used by boot up start-up script described later).
    to include necessary environment variables. 
    These files can be found here:
       startup.sh 
       shutdown.sh 
       jspc.sh 
       tomcat.sh 


    Started tomat
        cd $TOMCAT_HOME/bin
        ./startup.sh

    What worried me was the number of threads the Tomcat opened, namely
       ps auwx | grep java | wc -l
    gave over 40. But maybe this is not a problem, since these are
    lightweight threads which Linux now reports. 


18) Started Apache

       /etc/rc.d/init.d/httpd start

    It complained about missing link:
      Cannot load /etc/httpd/libexec/mod_jk.so into server: 
      /etc/httpd/libexec/mod_jk.so: cannot open shared object file: 
      No such file or directory

    Obviously, the httpd was not compiled tidely. I added a link:
   
       cd /etc/httpd
       ln -s ../../usr/lib/apache libexec

    And started Apache again:

       /etc/rc.d/init.d/httpd start

    This time, it did not bark.

    Then I tried: 
      http://pse.ccl.net/examples/jsp/
      https://pse.ccl.net/examples/jsp/
      http://pse.ccl.net/examples-test/jsp/
      https://pse.ccl.net/examples-test/servlets/    
    and I was clicking on examples and it all worked... (I think... {:-)}). 
    You will see major delays when you click on the JSP for the first time,
    but then, they load fast. 
    


19) Stopped Apache
       
       /etc/rc.d/init.d/httpd stop

20) Stopped Tomcat
        cd $TOMCAT_HOME/bin
        ./shutdown.sh
  
21) After 19) and 20) the Apache and Tomcat should be cleanly shut down.
    But it is good to check if zombies are not left:
        ps auwx | egrep 'httpd|java'
    and I was fine. If you are not, you need to kill those @!%#*^s and
    ask yourself: What did I do wrong? (since you obviously did -- it
    worked for me I swear (:-) -- BTW, is your apj12 protocol unabled in
    server.xml?).


22) Reconfigured Tomcat and Apache to do things I want them to do.

    a) In /etc/httpd/conf/httpd.conf made sure mod_jk is before mod_rewrite

      LoadModule jk_module          libexec/mod_jk.so
      LoadModule rewrite_module     libexec/mod_rewrite.so

    and

      AddModule mod_jk.c
      AddModule mod_rewrite.c

    and commented out the line

       # LoadModule jk_module libexec/mod_jserv.so

    in $TOMCAT_HOME/conf/mod_jk.conf

23) Created new users, in my case webinst, and webrun, and groups for
    them, home directories, and regular login environment.  

        adduser webinst
        passwd webinst
        adduser webrun
        passwd webrun

    In the /etc/passwd, I assigned /bin/bash for webrun, while webinst had
    /bin/tcsh as a primary shell (yes, I know that t/csh is brain dead, but
    people want it, and people will have it -- it sucks, e.g., with its
    limitations: "Word too long" when your environment variable is longer
    than 1024 -- it happens to me all the time with longer CLASSPATHs).
    Note that when you execute the script as
          su - uid -c script
    the script will be executed with the default shell (i.e., the shell
    which is assigned to the user in /etc/passwd), and it does not
    matter what you put in #!/bin/someshell on the top of your script.
    While under Linux (but not under all Unices), you can change the shell
    with a "-s" option to su, I wanted to keep things simple.
    The script is sourced with default shell, not forked with a new shell. 
    The webinst will own most of the files in the web site, while the
    webrun will be the user who runs the Apache server and the tomcat.
    It will own log files and other files which the apache/tomcat/ needs
    to write.  In /etc/httpd/conf/httpd.conf I changed apache to webrun:
       User webrun
       Group webrun

    I also changed names of the log files and pid files. To learn what
    I did, just run diff and see the differences between the default file
    which came with Apache distribution, and my incarnation.  
    My httpd.conf file after few changes looked like:
        httpd.conf
    Also chown_ed to webrun the log directories:
      chown -R webrun.webrun /var/log/httpd
    And for tomcat:
      chown -R webrun.webrun $TOMCAT_HOME/conf
      chown -R webrun.webrun $TOMCAT_HOME/logs
      chown -R webrun.webrun $TOMCAT_HOME/work



24) Now, I had to make a script which would start Tomcat/Apache on boot-up
    in unison. My understanding is that since Tomcat is a TCP server with
    respect to Apache, it should be started before Apache. Supposedly it does
    not matter much, but who knows. I derived the startup script
    from the original /etc/rc.d/init.d/httpd and saved it as:
    /etc/rc.d/init.d/httpd.jkl. I made sure that its exec permissions are on:
       chmod 755 /etc/rc.d/init.d/httpd.jkl    
    The copy of the script is here: 
      httpd.jkl

25) Started the apache/tomcat as:

       /etc/rc.d/init.d/httpd.jkl start

    and checked if http://pse.ccl.net/examples and
    https://pse.ccl.net/examples worked. Of course, you check
    www.yourmachine.com, not the pse.ccl.net.
   The examples worked, so I killed the server with:

        /etc/rc.d/init.d/httpd.jkl stop

    I also disabled the default RH7.0 Apache httpd which comes with the
    standard installation by executing:

      chkconfig --del httpd
    
    and then checked with:

      chkconfig --list httpd

    which showed rightly that httpd will not be invoked on boot:
      httpd           0:off   1:off   2:off   3:off   4:off   5:off   6:off

    Then, I made sure that the new httpd.jkl is used to start Apache/Tomcat
    at boot up:       

      chkconfig --add httpd.jkl
      chkconfig --list httpd.jkl

    with list giving me OK:
       httpd.jkl       0:off   1:off   2:off   3:on    4:on    5:on    6:off


26)Since starting/stopping apache+tomcat in this environment requires
   one to be a root, I created C wrappers to start and stop the whole zoo.
   apache_start.c.
   This is important when people who do not have root access do development.
   I compiled it with
     gcc -o apache_start apache_start.c
   as a root, and then added suid/sgid permissions to the resulting
   apache_start executable file as:
     chmod ug+s apache_start
   I put the file in /usr/local/bin directory, so it is usually in the
   user's PATH. Of course, you can check in these C wrappers if user is
   authorized to use it. I am checking if invoking user is webinst.

   I did exactly the same with apache_stop.c
      gcc -o apache_stop apache_stop.c  
      chmod ug+s apache_stop   
   apache_stop.c
   Now, people do not have to have root access to start/stop Web Server/Tomcat.
   They can just type:
      apache_stop
      apache_start
   to restart Apache/Tomcat combo.

   I also added a C program killme.c which kills the processes which are
   running by user webrun. It is intended to be used after "apache_stop"
   to kill some runaway processes started by apache, Tomcat, or JServ.
   After compiling the program:
      gcc -o killme killme.c
   changed its user and group ownership to webrun and added
   SETUID permission bits
      chown webrun killme
      chgrp webrun killme
      chmod ug+s killme
   To learn which processes need to be killed, the user does
       ps auwx | grep webrun | grep -v grep
   (I actually saved this line as a shell script "killwhich" so they can
   just type: killwhich).
   and the user can kill the processes listed by previous command as:
       killme pid1 pid2 ....
   where pidn is the process id number in the second column.