tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From André Warnier (tomcat) ...@ice-sa.com>
Subject Re: Question about setting CATALINA_OPTS when starting Tomcat using a Windows Service in Tomcat 7.0.54
Date Thu, 09 Aug 2018 16:39:52 GMT
Maybe it is time here to quote Arthur Clarke's 3rd law :
"Any sufficiently advanced technology is indistinguishable from magic"
(See : https://en.wikipedia.org/wiki/Clarke%27s_three_laws)

The process by which Tomcat is started and/or stopped - particularly under Windows and as

a Service - is not very clear in the on-line documentation.
Neither is it it very easy to write a comprehensive and accurate documentation, because 
the thing has gotten to a point where, for mere mortals, it is really quite complicated.
(Have a look at bin/catalina.bat to get an idea).

So let me give you some overall pointers (some of them quite basic, I apologise), and 
maybe in there somewhere, you'll find wat you are missing to complete the picture and do 
what you want to do.

1) Tomcat is a compiled java application, in java bytecode.  To run this bytecode, you 
need a JVM. The JVM is machine-executable code, so to run tomcat, you run a JVM and tell 
it to run the tomcat bytecode.
2) the java JVM for Windows is not very good at running as a Windows Service (it does not

handle the appropriate Windows "signals" etc.). To solve this, when you want to run tomcat

as a Windows Service (or rather - see above - run the JVM as a Windows Service), you 
actually run a specialised "wrapper program" which does work well as a Windows Service, 
and you ask this wrapper to start the JVM which runs tomcat.
To make matters a bit more confusing (or maybe, for some, clearer), this generic "Windows

Service JVM wrapper" is renamed to "tomcatV.exe" (where V is the tomcat version, so for 
tomcat 9, the program is called tomcat9.exe).
3) the wrapper program, when it starts the JVM, has to know which command-line switches it

should pass to it.  For the Windows Service flavor of tomcat, these parameters are stored

in a number of special keys in the Windows Registry, and that is where the wrapper picks 
them up, before starting the JVM.
4) To make it easier to set and edit these JVM command-line parameters, tomcat provides 
another Windows executable program - a specialised GUI Registry Editor - which is also 
renamed according to the tomcat version, as tomcatVw.exe (where V is the tomcat version, 
so for tomcat 9 it would be tomcat9w.exe).

5) as a separate bit of knowledge, I would suppose that everyone knows that on any given 
host, a given TCP listening port can only be opened by one process at a time. If a second

process tries to open a port which is already opened by a first process, it will get an 
error of the kind "port already in use", and most probably the second process will then 
exit (non-gracefully).

6) in the tomcat conf/server.xml file, there is a tag :
<Server port="8005" shutdown="SHUTDOWN">
This provides a clue as to how one actually *stops* tomcat : one opens a TCP connection to

locahost port 8005 (on which tomcat listens), then sends the string "SHUTDOWN" on that 
connection. This causes tomcat to shutdown gracefully, at the end of which it does a 
"system.exit()" which shuts down the JVM that runs it.
And this in turn causes the JVM wrapper program to tell Windows that the tomcat Service is

shutting down, before itself exiting. And thus is all well and tidy in the Windows Service

world.

7) a helpful feature of tomcat, is that it itself provides code to connect to localhost 
port 8005 and send that shutdown string, so that one does not have to write its own 
separate program to do that.
The bit that is a bit confusing about this feature however, is that in order to use that 
code, one of course needs to start up another separate instance of tomcat, just to run 
that code and actually stop the "real" running tomcat.
And of course running a separate instance of tomcat actually means running a separate 
instance of the JVM which runs tomcat.

Now armed with all the above knowledge, and with the dialog window offered by the 
tomcat9w.exe program, it is relatively easy to figure out what happens (or at least what 
may happen in your case, in my modest non-java-expert opinion).

Looking only at the last 3 tabs of that window (Java / Startup / Shutdown), one can figure

out that :
- the "java" tab contains the path of the JVM to be started, and the command-line 
parameters that will be passed to that JVM
- the "Startup" tab contains the java class that the JVM should invoke at the start of 
tomcat, and the argument ("start") to pass into that initial call.
- the "Shutdown" tab contains the java class that the JVM should invoke to stop an 
already-running tomcat, and the argument ("stop") to pass into that initial call.
(Thus triggering the code in (7) above).

And I believe that, in the particular case of Tomcat being run as a Windows Service, here

may be the origin of the problem which you are encountering : the "Java" tab lists 
command-line options that are *common* to both the JVM which starts tomcat, and to the 
(separate) JVM which stops tomcat.  There is only one set of JVM options, for both cases.
Which means that if, in these JVM command-line options, you pass it one that tells the JVM

to open some extra listening port (which you do to enable JMX), then this will happen both

when a JVM is started because tomcat is being started, and when a JVM is started because 
tomcat is being stopped.
And of course the second one will fail, because the first one has already opened that port.

(Note that this will happen no matter which level of indirection you build into the 
Registry JVM parameters.)

Why does that happen only with that JMX port, and not with the other listening ports that

tomcat opens ?
Well, that is a question of /when/ these different things happen : the JMX-port 
command-line parameter "happens" earlier, because it is something that the JVM does, 
before it evens starts running tomcat bytecode.
While the other ports that Tomcat opens, happen in the code of tomcat itself, when it is 
being run. And that tomcat code is smart enough to know that when it is being run with the

argument "stop", then it should not open these other ports mentioned in its configuration

file.

On the face of it, it seems a bit of an unsolvable issue, unless the tomcat Service 
wrapper code is changed, to allow for 2 separate sets of JVM parameters (one for start, 
with the JMX options; and one for stop, without these options).
Or unless something is done in the Tomcat code itself, to allow JMX to be started (or not)

from within Tomcat (assuming that's even possible).

Of course, one could also wonder if you really need JMX when you run tomcat in production

mode.  If this is only for testing, you could run tomcat in a console, where you would not

have the same issue (because you would not have the wrapper with its single-minded preset

JVM options).

(Or you could switch to Linux ;-))

On 09.08.2018 02:06, Daniel Savard wrote:
> Le mer. 8 août 2018 à 12:08, Louis Zipes <Louis.Zipes@gmcr.com> a écrit :
>
>>
>> Hi Calder,
>> I can successfully start up as a Windows service and get JMX working BUT
>> my problem is that Service doesn't stop cleanly (just repeating that
>> problem in case it wasn't made clear).  It says the PORT is already in use
>> which led me to try to use Catalina_Opts as per the suggestions on the
>> internet.
>>
>> Port already in use: 8008; nested exception is:
>>                 java.net.BindException: Address already in use: JVM_Bind
>>
>> If you were able to get JMX working and you can start AND stop the Tomcat
>> service cleanly, do you mind sharing me your 'scrubbed'  Java tab contents
>> as I can seem to get the right combination to get it to Start and Stop the
>> service.
>>
>> Thanks, Louis
>>
>>
>>
> Louis,
>
> I believe you need to understand a bit more how things are working with
> Java and the JVM. The -D options are pretty straight forward for anyone
> knowing how you define properties to the JVM on the command line. I already
> told you everything you need to know to setup properly your Tomcat. Since
> you were the one talking about CATALINA_OPTS I assumed you did know where
> and how to setup the variable for your installation. Otherwise, just go in
> the setup utility for Tomcat on Windows and put the
> -Dcom.sun.management.conf.file=${catalina.base}/conf/abc.def entry there
> without the CATALINA_OPTS= stanza since this one's intent is to set an
> environment variable for the process to pick while the former is passing
> directly the property to the JVM from the Tomcat Windows Setup dialog.
> There is many ways to do things. Bottom line, you need to tell the JVM
> where is the configuration file for JMX and put your properties in there as
> any other properties file. This is standard stuff.
>
> The effect is the JVM now knows your port is a JMX port and it will stop to
> try to use it when it is already in use and free it cleanly.
>
> Regards,
>
> -----------------
> Daniel Savard
>
>
>>
>>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Mime
View raw message