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_