Hi All,

I've identified the following problem when starting and stopping
the Apache Jakarta Tomcat Application in stand-alone mode, under
control of the Software Firewall ZoneAlarm on Windows/NT and just
wanted to let you know about my findings.

This bug(?) has been reported to the Apache Bugzilla Database,
the Java Developer Connection's Bug Database, and to ZoneLabs.

Maybe it is the root of several of the problems being reported
by others for Tomcat.

Don't panic - yes, it is an awful lot of text, hmm, but ... ;-)

Rolf

____________________
Start of Bug Report:

Windows/NT + ZoneAlarm + Apache Jakarta Tomcat - start/stop - 2nd time

  =>java.net.ConnectException: Connection refused: connect
        at java.net.PlainSocketImpl.socketConnect(Native method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:320)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:133)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:120)
        at java.net.Socket.<init>(Socket.java:273)
        at java.net.Socket.<init>(Socket.java:100)
        at org.apache.tomcat.task.StopTomcat.execute(StopTomcat.java:104)
        at org.apache.tomcat.startup.Tomcat.stopTomcat(Tomcat.java:267)
        at org.apache.tomcat.startup.Tomcat.execute(Tomcat.java:174)
        at org.apache.tomcat.startup.Tomcat.main(Tomcat.java:235)

  This exception is thrown, under the conditions described below, when
  trying to stop the Jakarta Tomcat Servlet Container, when running in
  standalone mode on Windows/NT 4.0 (build 1381, sp3) with ZoneAlarm 2.6
  (build 2.6.231) Software Firewall installed.

  Conditions:

        *). (without quotes, at DOS command level in a Command Prompt window)

        1). Install or make sure Java SDK v3.1 from Sun is installed.

        2). Install or make sure ZoneAlarm Firewall Software is installed.
        3). Make sure ZoneAlarm gives all right to JVM, under 'Programs' tab.
            i.e. java.exe [Local:    Allow connect {true}, Allow Server {true}]
                          [Internet: Allow connect {true}, Allow Server {true}]

        4). Make a default vanilla installation of Jakarta Tomcat v3.2.3,
            by default running ajpv12 connection handler on port 8007,
            and http connection handler on port 8080 (see logs).

        5). Edit the 'Tomcat.bat' file in '<TOMCAT_HOME>\bin'
            (let's not use the 'startup' and 'shutdown' scripts,
             as they only forward their resposibilities to the
             'tomcat.bat' script anyway). 

            After the header rows append:

                rem --- Explicitly Define Environment Variables ---

                set CLASSPATH=
                set JAVA_HOME=yourPathToJavaVirtualMachineGoesHere
                set TOMCAT_HOME=yourPathToTomcatHomeGoesHere

            ... to clear the default system classpath, and
                specifying the directory of where you have
                installed your Java Virtual Machine and Tomcat.

            Optionally, after the header rows append:

                rem define all variables local to script only
                setlocal

            Optionally, after row ':finish' at the end of the file append:

                rem end of locally defined variables
                endlocal

            Done.

        6). Reboot (to ensure all ports and connections are closed, etc)

        7). Change directory to <TOMCAT_HOME>, i.e. Tomcat install directory.
        8). Look at status of ports by entering(*): 'netstat -an | find ":80"'
            This will show an empty line as result (at least after a reboot,
            and unless another process opens anything on a port 80### )
        9). Start Tomcat by entering(*): 'bin\tomcat start'
            This will start up the Tomcat Server in another Command Window.
        10) Now look at status of ports by entering: 'netstat -an | find ":80"'
            =>  TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8080            0.0.0.0:0       LISTENING
            # ok - Tomcat started and ready! - see log files.   
        11) Now, without even attempting to make any http access to Tomcat,
            shut it down by entering(*): 'bin\tomcat stop'
            This will stop the Tomcat Server and closing the Tomcat Window
            and everyting seems to be okey. - Doesn't it? But.
        12) Once again check the status of the ports, which will show
            something like this:
            =>  TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     127.0.0.1:1030          127.0.0.1:8007  TIME_WAIT
            # Does this look okey? - No I don't think so. The connection
            # handler seems still be listening for connections. Doesn't it?
        13) If we re-check the status of the ports after a while, i.e. after
            about 5 minutes, the TIME_WAIT tagged line will have gone away:
            =>  TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
            # But the connection handler is still there. It never gets closed.

        14) Now, restart Tomcat once again, i.e.: 'bin\tomcat start'
            This will once again start up the Tomcat Server in another Window.
            Checking the status of the ports now displays:
            =>  TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8080            0.0.0.0:0       LISTENING
            # Suddenly we have TWO connection handlers!?
        15) Stopping Tomcat now, i.e.: 'bin\tomcat stop'
            will render the exception above, in the Command Window where
            the stop command was typed. This time though without stopping
            Tomcat and thus leaving the Tomcat Command Window up and running.
            Checking the status of the ports, now shows no change:
            =>  TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8080            0.0.0.0:0       LISTENING
            # This comes as no surprise as the Tomcat connection handler,
              which handles the shutdown request, refuesed the
connection
              from the stop-process under control of the ZoneAlarm Firewall.
        16) The only way to stop the Tomcat Server now is by typing a ctrl-c
            into the Command Window of the Tomcat Server.
            This effectively kills the Tomcat Server and closes it's 2 ports.
            Checking the status of the ports, now shows:
            =>  TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
            # Thus the connection handler of the first started Tomcat Server,
              which was stopped whithout throwing an exception, still lingers
              around.

        Note! The Tomcat logfiles don't indicate any problems.

  Validation:

        Now, don't start ZoneAlarm True Vector Services at startup
        by unchecking 'Load ZoneAlarm at startup' on ZoneAlarm's
        'Configure' panel, before stopping ZoneAlarm and rebooting.

        Repeating the steps described under "Conditions" above,
        this time without the ZoneAlarm Firewall (with it's
        True Vector Services running), will make Tomcat run
        as originally intended (my guess). I.e:

        - Status of ports after first start up:
            =>  TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8080            0.0.0.0:0       LISTENING
        - Status of ports after first shut down:
                TCP     127.0.0.1:1030          127.0.0.1:8007  TIME_WAIT
        - Status of ports a while thereafter:
                 -            -                       -             -
        - ... and so on for every start and stop.

  Why this is a problem:

        Okey, if the Tomcat Server's ports close when stopping
        by giving ctrl-c, then why not use that instead of the
        'bin\tomcat stop' command?

        - first of all - I'm not sure Tomcat catches the ctrl-c
          correctly and thus is allowed to do any cleanup required.

        - secondly - How do you specify the ctrl-c when you run
          the Tomcat Server as a Windows service? ;-)

        - third - After having made a http reference on port 8080
          that port will linger around, even after a ctrl-c, in the
          same way as port 8007 did after the first shut down, and
          thus it will be impossible to reconnect to the Tomcat Server
          via http on port 8080 (even if you start up another Tomcat).

          Status of ports after startup, http access, and ctrl-c:
            =>  TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8080            0.0.0.0:0       LISTENING

          Status of ports after startup, http access, and ctrl-c
          and startup of a second Tomcat Server process:
            =>  TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8080            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8080            0.0.0.0:0       LISTENING

          Status of ports after stopping (ctrl-c) the second Tomcat Server:
            =>  TCP     0.0.0.0:8007            0.0.0.0:0       LISTENING
                TCP     0.0.0.0:8080            0.0.0.0:0       LISTENING

          So, now a REBOOT IS REQUIRED (unless you know another way
          of releasing the ports) before you can go on, e.g. testing
          modifications to the Tomcat config files, etc. Sick!

  Why this is important:
                
        ZoneAlarm is considered being one of the most decent and secure
        Software Firewalls around today. It's free for non-commercial use.
        See: http://www.zonealarm.com/

        Tomcat being the reference implementation for Java Servlets and
        Java Server Pages is also free, as well as being Open Source.
        See: http://jakarta.apache.org/

        Software development and testing is very expensive, thus the vast
        majority of independent software developers, home users, and start-
        ups are very dependant on reliable low-/no-cost software for their
        future success. Software like the ones mentioned above thus make a
        important and natural platform for many many developers around the
        world.

        Therefore it is very important that we find and solve fundamental
        bugs like this one. Solving them at the root once, for all, saves 
        developers valuable time so they can focus on their development(
        instead of wasting time by seeking for the same problem as have
        others), thus hopfully in the future giving us the _best_ solutions
        instead of the solutions those the big money provides us with.

        It's unacceptable to require a reboot of a system after every
        modification to the configuration of an application before one
        can test it again. At least if we want it to succeed and survive.

        And this might also be the source of other annoying problems
        reported with Tomcat.

  Conclusions:

        The problem arises when running Jakarta Tomcat under
        the control of the ZoneAlarm Software Firewall.

        A port will stay in state LISTEN after a connection has been
        made to it. This applies to the connection handler, e.g. via
        'bin\tomcat stop', as well as to the http connection handler,
        via 'http://localhost:8080/' by means of some web browser.

        It's not possible to run Tomcat as a Windows Service whilst
        maintaining reliable cleanup procedures during shut down,
        and at the same time be protected by a software firewall
        like ZoneAlarm (what about others?).

  Solving the bug:

        Hint for solving this bug (by ZoneAlarm and/or Tomcat developer):

        - first step    - make sure Tomcat can be started and stopped
                          via 'bin\tomcat start' and 'bin\tomcat stop'
                          unlimited times under control of ZoneAlarm,
                          thereby opening and closing ports correctly,
                          given full access to JVM, i.e. java.exe,
                          for 'Allow connect' and 'Allow server'.
        - second step   - make sure Tomcat works equally when making
                          when making http requests before stopping.
        - third  step   - make sure Tomcat can handle the situation
                          when either the 'Internet zone' (most likely)
                          or the 'Local zone' (less likely) does not
                          have server rights by ZoneAlarm, i.e.
                          'Allow Server' for java.exe is blocked for
                          either 'Local' or 'Internet'.

        I would start with investigating how the ports are opened,
        i.e. if they are specified as '127.0.0.1', 'localhost', or
        explicitly by the host's ip-address, and make sure the same
        method is used everywhere. Then experimenting wether using
        another method, i.e. (most likely) '127.0.0.1', would solve
        the problem. (I haven't checked the source myself due to
        lack of time, and experience I guess :-( )

  Final note:

        This bug has been reported to:

        The Apache Bug Database, i.e. Jakarta Tomcat Bugzilla.
        http://jakarta.apache.org/site/bugs.html
        where it received bug id: 3319

        The Java Developer Connection's Bug Database,
        as a Java 2 SDK, Standard Edition bug (I guess?).
        
        As well as to Zone Labs, http://www.zonealarm.com/, i.e. at
        http://www3.zonelabs.com:8080/cgi-bin/support/support_req.pl

./.

-- 
----
------
--------

Rolf Sponsel

___________________________________________e_n_d___o_f___m_e_s_s_a_g_e_

Reply via email to