zdcshh 发表于 2013-2-7 03:36:32

Tomcat笔记2(启动脚本startup.bat分析)

Tomcat(7.0)的bin目录下包含startup.bat和catalina.bat,启动执行startup.bat之后,会在其中call catalina.bat执行。

starup.bat:
rem 之前的声明省略   rem Guess CATALINA_HOME if not defined   rem 确定环境变量CATALINA_HOME 被定义   set "CURRENT_DIR=%cd%"if not "%CATALINA_HOME%" == "" goto gotHome   set "CATALINA_HOME=%CURRENT_DIR%"if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome   cd ..   set "CATALINA_HOME=%cd%"cd "%CURRENT_DIR%":gotHome   if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome   echo The CATALINA_HOME environment variable is not defined correctly   echo This environment variable is needed to run this program   goto end   :okHome   set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"    rem Check that target executable exists   rem 定义执行目标文件赋值给变量EXECUTABLE   if exist "%EXECUTABLE%" goto okExec   echo Cannot find "%EXECUTABLE%"echo This file is needed to run this program   goto end   :okExec   rem Get remaining unshifted command line arguments and save them in the   rem 参数验证及格式转换   set CMD_LINE_ARGS=   :setArgs   if ""%1""=="""" goto doneSetArgs   set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1   shift   goto setArgs   :doneSetArgs   rem 之前都是变量验证,格式检查,参数验证等预处理   rem 这一步才是核心   call "%EXECUTABLE%" start %CMD_LINE_ARGS%   :end

之后调用catalian.bat文件,传入参数start,如果startup中包含参数也一并传入给catalina.
rem 验证系统版本Windwos_NT   rem Windows 2000, Windows XP, Windows Server 2003, Windows Vista, Windows Home Server, rem Windows Server 2008 and Windows 7 are based on Windows NT, although they are not branded as Windows NT.   if "%OS%" == "Windows_NT" setlocal   rem ---------------------------------------------------------------------------   rem Start/Stop Script for the CATALINA Server   rem   rem Environment Variable Prequisites   rem   rem   CATALINA_HOME   May point at your Catalina "build" directory.   rem   rem   CATALINA_BASE   (Optional) Base directory for resolving dynamic portions   rem                   of a Catalina installation.If not present, resolves to   rem                   the same directory that CATALINA_HOME points to.   rem   rem   CATALINA_OPTS   (Optional) Java runtime options used when the "start",   rem                   or "run" command is executed.   rem   rem   CATALINA_TMPDIR (Optional) Directory path location of temporary directory   rem                   the JVM should use (java.io.tmpdir).Defaults to   rem                   %CATALINA_BASE%\temp.   rem   rem   JAVA_HOME       Must point at your Java Development Kit installation.   rem                   Required to run the with the "debug" argument.   rem   rem   JRE_HOME      Must point at your Java Runtime installation.   rem                   Defaults to JAVA_HOME if empty.   rem   rem   JAVA_OPTS       (Optional) Java runtime options used when the "start",   rem                   "stop", or "run" command is executed.   rem   rem   JAVA_ENDORSED_DIRS (Optional) Lists of of semi-colon separated directories   rem                   containing some jars in order to allow replacement of APIs    rem                   created outside of the JCP (i.e. DOM and SAX from W3C).    rem                   It can also be used to update the XML parser implementation.   rem                   Defaults to $CATALINA_HOME/endorsed.   rem   rem   JPDA_TRANSPORT(Optional) JPDA transport used when the "jpda start"rem                   command is executed. The default is "dt_socket".   rem   rem   JPDA_ADDRESS    (Optional) Java runtime options used when the "jpda start"rem                   command is executed. The default is 8000.   rem   rem   JPDA_SUSPEND    (Optional) Java runtime options used when the "jpda start"rem                   command is executed. Specifies whether JVM should suspend   rem                   execution immediately after startup. Default is "n".   rem   rem   JPDA_OPTS       (Optional) Java runtime options used when the "jpda start"rem                   command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,   rem                   and JPDA_SUSPEND are ignored. Thus, all required jpda   rem                   options MUST be specified. The default is:   rem   rem                   -agentlib:jdwp=transport=%JPDA_TRANSPORT%,   rem                     address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%   rem   rem   LOGGING_CONFIG(Optional) Override Tomcat's logging config file   rem                   Example (all one line)   rem                   set LOGGING_CONFIG="-Djava.util.logging.config.file=%CATALINA_BASE%\conf\logging.properties"rem   rem   LOGGING_MANAGER (Optional) Override Tomcat's logging manager    rem                   Example (all one line)   rem                   set LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"rem   rem   TITLE         (Optional) Specify the title of Tomcat window. The default   rem                   TITLE is Tomcat if it's not specified.   rem                   Example (all one line)   rem                   set TITLE=Tomcat.Cluster#1.Server#1 [%DATE% %TIME%]   rem   rem   rem   rem $Id: catalina.bat 947837 2010-05-24 22:19:23Z kkolinko $   rem ---------------------------------------------------------------------------   rem Suppress Terminate batch job on CTRL+C   if not ""%1"" == ""run"" goto mainEntry   if ""%TEMP%"" == """" goto mainEntry   if exist "%TEMP%\%~nx0.run" goto mainEntry   echo Y>"%TEMP%\%~nx0.run"if not exist "%TEMP%\%~nx0.run" goto mainEntry   echo Y>"%TEMP%\%~nx0.Y"call "%~f0" %* <"%TEMP%\%~nx0.Y"rem Use provided errorlevel   set RETVAL=%ERRORLEVEL%   del /Q "%TEMP%\%~nx0.Y" >NUL 2>&1   exit /B %RETVAL%   :mainEntry   del /Q "%TEMP%\%~nx0.run" >NUL 2>&1   rem 设定CATALINA环境变量   rem Guess CATALINA_HOME if not defined   set "CURRENT_DIR=%cd%"if not "%CATALINA_HOME%" == "" goto gotHome   set "CATALINA_HOME=%CURRENT_DIR%"if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome   cd ..   set "CATALINA_HOME=%cd%"cd "%CURRENT_DIR%":gotHome   if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome   echo The CATALINA_HOME environment variable is not defined correctly   echo This environment variable is needed to run this program   goto end   :okHome   rem Ensure that any user defined CLASSPATH variables are not used on startup,   rem but allow them to be specified in setenv.bat, in rare case when it is needed.   set CLASSPATH=   rem 取得CATALINA环境变量   rem Get standard environment variables   if "%CATALINA_BASE%" == "" goto gotSetenvHome   if exist "%CATALINA_BASE%\bin\setenv.bat" call "%CATALINA_BASE%\bin\setenv.bat"goto gotSetenvBase   :gotSetenvHome   if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat":gotSetenvBase   rem Get standard Java environment variables   if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath   echo Cannot find "%CATALINA_HOME%\bin\setclasspath.bat"echo This file is needed to run this program   goto end   :okSetclasspath   set "BASEDIR=%CATALINA_HOME%"call "%CATALINA_HOME%\bin\setclasspath.bat" %1   if errorlevel 1 goto end   rem Add on extra jar file to CLASSPATH   rem Note that there are no quotes as we do not want to introduce random   rem quotes into the CLASSPATH   if "%CLASSPATH%" == "" goto emptyClasspath   set "CLASSPATH=%CLASSPATH%;":emptyClasspath   set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar"    if not "%CATALINA_BASE%" == "" goto gotBase   set "CATALINA_BASE=%CATALINA_HOME%":gotBase   if not "%CATALINA_TMPDIR%" == "" goto gotTmpdir   set "CATALINA_TMPDIR=%CATALINA_BASE%\temp":gotTmpdir   rem Add tomcat-juli.jar to classpath   rem tomcat-juli.jar can be over-ridden per instance   if not exist "%CATALINA_BASE%\bin\tomcat-juli.jar" goto juliClasspathHome   set "CLASSPATH=%CLASSPATH%;%CATALINA_BASE%\bin\tomcat-juli.jar"goto juliClasspathDone   :juliClasspathHome   set "CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\bin\tomcat-juli.jar":juliClasspathDone   if not "%LOGGING_CONFIG%" == "" goto noJuliConfig   set LOGGING_CONFIG=-Dnop   if not exist "%CATALINA_BASE%\conf\logging.properties" goto noJuliConfig   set LOGGING_CONFIG=-Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties":noJuliConfig   set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%   if not "%LOGGING_MANAGER%" == "" goto noJuliManager   set LOGGING_MANAGER=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager   :noJuliManager   set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%   rem ----- Execute The Requested Command ---------------------------------------   echo Using CATALINA_BASE:   "%CATALINA_BASE%"echo Using CATALINA_HOME:   "%CATALINA_HOME%"echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%"if ""%1"" == ""debug"" goto use_jdk   echo Using JRE_HOME:      "%JRE_HOME%"goto java_dir_displayed   :use_jdk   echo Using JAVA_HOME:       "%JAVA_HOME%":java_dir_displayed   echo Using CLASSPATH:       "%CLASSPATH%"    set _EXECJAVA=%_RUNJAVA%   set MAINCLASS=org.apache.catalina.startup.Bootstrap   set ACTION=start   set SECURITY_POLICY_FILE=   set DEBUG_OPTS=   set JPDA=   if not ""%1"" == ""jpda"" goto noJpda   set JPDA=jpda   if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport   set JPDA_TRANSPORT=dt_socket   :gotJpdaTransport   if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress   set JPDA_ADDRESS=8000   :gotJpdaAddress   if not "%JPDA_SUSPEND%" == "" goto gotJpdaSuspend   set JPDA_SUSPEND=n   :gotJpdaSuspend   if not "%JPDA_OPTS%" == "" goto gotJpdaOpts   set JPDA_OPTS=-agentlib:jdwp=transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%   :gotJpdaOpts   shift   :noJpda   if ""%1"" == ""debug"" goto doDebug   if ""%1"" == ""run"" goto doRun   if ""%1"" == ""start"" goto doStart   if ""%1"" == ""stop"" goto doStop   if ""%1"" == ""version"" goto doVersion   rem 想到Linux下面的各种命令行的shell程序 很类似   echo Usage:catalina ( commands ... )   echo commands:   echo   debug             Start Catalina in a debugger   echo   debug -security   Debug Catalina with a security manager   echo   jpda start      Start Catalina under JPDA debugger   echo   run               Start Catalina in the current window   echo   run -security   Start in the current window with security manager   echo   start             Start Catalina in a separate window   echo   start -security   Start in a separate window with security manager   echo   stop            Stop Catalina   echo   version         What version of tomcat are you running?   goto end   rem 之前都是预处理,到这里才开始真正进行分支调用   :doDebug   shift   set _EXECJAVA=%_RUNJDB%   set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%\..\..\java"if not ""%1"" == ""-security"" goto execCmd   shift   echo Using Security Manager   set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"goto execCmd   :doRun   shift   if not ""%1"" == ""-security"" goto execCmd   shift   echo Using Security Manager   set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"goto execCmd   :doStart   shift   if not "%OS%" == "Windows_NT" goto noTitle   if "%TITLE%" == "" set TITLE=Tomcat   set _EXECJAVA=start "%TITLE%" %_RUNJAVA%   goto gotTitle   :noTitle   set _EXECJAVA=start %_RUNJAVA%   :gotTitle   if not ""%1"" == ""-security"" goto execCmd   shift   echo Using Security Manager   set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"goto execCmd   :doStop   shift   set ACTION=stop   set CATALINA_OPTS=   goto execCmd   :doVersion   %_EXECJAVA% -classpath "%CATALINA_HOME%\lib\catalina.jar" org.apache.catalina.util.ServerInfo   goto end       :execCmd   rem Get remaining unshifted command line arguments and save them in the   set CMD_LINE_ARGS=   :setArgs   if ""%1""=="""" goto doneSetArgs   set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1   shift   goto setArgs   :doneSetArgs   rem --------------------------------------------------------------------------------- rem   rem Execute Java with the applicable properties   rem 这里才是真正要执行的jvm命令   if not "%JPDA%" == "" goto doJpda   if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity   %_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%   goto end   :doSecurity   %_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%   goto end   :doJpda   if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda   %_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%   goto end   :doSecurityJpda   %_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %JPDA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Djava.security.manager -Djava.security.policy=="%SECURITY_POLICY_FILE%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%   goto end   :end

其中,":label名"不代表一个过程,只是代表其本身一个程序点而已,原来总以为是个类似函数或者过程定义的东西,现在看来,它只代表自己而已,仅仅是告诉goto语句跳到这个点上。
%_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE%" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION%
这段代码才是jvm(对应java命令)执行的总命令行,其中传入了各种参数,即在startup.bat中调用catalina,根据传入命令(e.g. start..)选择对应入口,由于在之前已经设定好了环境变量,等各种参数检查(统称为预处理),直到这里才是真正进行了jvm启动。

echo了一下,最终启动命令为:
start "Tomcat" "C:\Program Files\Java\jdk1.6.0_21\bin\java"-Djava.util.logging.config.file="D:\work_ju\tomcat7.0\output\build\conf\logging.properties" -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager    -Djava.endorsed.dirs="D:\work_ju\tomcat7.0\output\build\endorsed" -classpath "D:\work_ju\tomcat7.0\output\build\bin\bootstrap.jar;D:\work_ju\tomcat7.0\output\build\bin\tomcat-juli.jar" -Djava.security.manager -Djava.security.policy=="" -Dcatalina.base="D:\work_ju\tomcat7.0\output\build" -Dcatalina.home="D:\work_ju\tomcat7.0\output\build" -Djava.io.tmpdir="D:\work_ju\tomcat7.0\output\build\temp" org.apache.catalina.startup.Bootstrapstart
可以看到关于启动环境的各种具体配置。
set MAINCLASS=org.apache.catalina.startup.Bootstrap
bat中此处设定了jvm的虚拟机入口,即main函数,可以看到是交由Bootstrap类进行的,它被提供给classloader加载,并执行main()。

这也类似开源框架中的load-on-startup为1的servlet,交给servlet容器给予启动。而其init方法则可类比为main函数,只是main函数是交给虚拟机启动的,而init方法是交给servlet容器,通过java反射由servlet容器进行启动。

在tomcat的web.xml文件当中,定义load-on-startup的servlet是org.apache.catalina.servlets.DefaultServlet,它只有一个子类,即WebdavServlet,根据规范,在init()方法中进行ServletContext和ServletConfig的初始化,service()起到一个选择doGet(),doPost(),doHead()等方法的分派作用,所以只在子类的WebdavServlet当中定义该方法,doGet(),doPost()的基础性工作都在父类DefaultServlet当中完成。
http://dl.iteye.com/upload/attachment/335317/33f882ea-34ec-3838-b7c7-5636bebf6c4c.jpg

注:
1.CATALINA_BASE 定义:
#CATALINA_BASE
#(Optional) Base directory for resolving dynamic portions
#of a Catalina installation.If not present, resolves to
#the same directory that CATALINA_HOME points to.

2.关于启动命令及参数:

在tomcat启动之后,也可以通过sun提供内存查看工具jconsole查看最终启动参数和各项内存情况。

http://dl.iteye.com/upload/attachment/335319/9ee3f4c9-aef7-32ea-870f-96464feae4a9.jpg
页: [1]
查看完整版本: Tomcat笔记2(启动脚本startup.bat分析)