Tomcat源码学习--启动脚本

201 阅读11分钟

1.startup.bat

@echo off
rem Licensed to the Apache Software Foundation (ASF) under one or more
rem contributor license agreements.  See the NOTICE file distributed with
rem this work for additional information regarding copyright ownership.
rem The ASF licenses this file to You under the Apache License, Version 2.0
rem (the "License"); you may not use this file except in compliance with
rem the License.  You may obtain a copy of the License at
rem
rem     http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rem See the License for the specific language governing permissions and
rem limitations under the License.

rem ---------------------------------------------------------------------------
rem Start script for the CATALINA Server
rem ---------------------------------------------------------------------------

setlocal

rem Guess CATALINA_HOME if not defined
rem 获取当前绝对路径并赋值给CURRENT_DIR
set "CURRENT_DIR=%cd%"
rem 判断环境变量(CATALINA_HOME)是否为空,如果不为空直接跳转到gotHome
if not "%CATALINA_HOME%" == "" goto gotHome
rem 如果环境变量(CATALINA_HOME)为空,则将CURRENT_DIR(当前绝对路径)赋值给 CATALINA_HOME
set "CATALINA_HOME=%CURRENT_DIR%"
rem 如果当前路径下存在 \bin\catalina.bat 则直接跳转到okHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
cd ..
rem 这里设置catalina的环境变量
set "CATALINA_HOME=%cd%"
cd "%CURRENT_DIR%"
:gotHome
rem 判断catalina环境变量下是否存在 \bin\catalina.bat,如果存在直接跳转到okHome
if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
rem 不存在则报错
echo The CATALINA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
goto end
:okHome
rem 给EXECUTABLE赋值 :%CATALINA_HOME%\bin\catalina.bat 
set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"

rem Check that target executable exists
rem 判断 %CATALINA_HOME%\bin\catalina.bat 路径是否合法,如果合法直接跳转okExec
if exist "%EXECUTABLE%" goto okExec
rem 如果不存在 直接报错
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 CMD_LINE_ARGS
rem 获取剩余的未移位命令行参数,并将其保存在 CMD_LINE_ARGS
set CMD_LINE_ARGS=
:setArgs
rem 这里是根据参数循环设置值,即将参数一个以一个使用shift移位,
rem 实际上我们在点击bat脚本时 并没有传递任何参数,
rem 所以 CMD_LINE_ARGS 执行完之后还是一个空字符串
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
rem 最后CMD_LINE_ARGS 实际就是调用该程序时的参数
:doneSetArgs
rem 前面取到的 EXECUTABLE 值实际就是 catalina.bat 文件的绝对路径
rem  call执行catalina.bat文件进行后续处理
call "%EXECUTABLE%" run %CMD_LINE_ARGS%

:end

2.catalina.bat

@echo off
rem Licensed to the Apache Software Foundation (ASF) under one or more
rem contributor license agreements.  See the NOTICE file distributed with
rem this work for additional information regarding copyright ownership.
rem The ASF licenses this file to You under the Apache License, Version 2.0
rem (the "License"); you may not use this file except in compliance with
rem the License.  You may obtain a copy of the License at
rem
rem     http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rem See the License for the specific language governing permissions and
rem limitations under the License.

rem ---------------------------------------------------------------------------
rem Start/Stop Script for the CATALINA Server
rem
rem Environment Variable Prerequisites
rem
rem   Do not set the variables in this script. Instead put them into a script
rem   setenv.bat in CATALINA_BASE/bin to keep your customizations separate.
rem
rem   WHEN RUNNING TOMCAT AS A WINDOWS SERVICE:
rem   Note that the environment variables that affect the behavior of this
rem   script will have no effect at all on Windows Services. As such, any
rem   local customizations made in a CATALINA_BASE/bin/setenv.bat script
rem   will also have no effect on Tomcat when launched as a Windows Service.
rem   The configuration that controls Windows Services is stored in the Windows
rem   Registry, and is most conveniently maintained using the "tomcatXw.exe"
rem   maintenance utility, where "X" is the major version of Tomcat you are
rem   running.
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                   "run" or "debug" command is executed.
rem                   Include here and not in JAVA_OPTS all options, that should
rem                   only be used by Tomcat itself, not by the stop process,
rem                   the version command etc.
rem                   Examples are heap size, GC logging, JMX ports etc.
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. If JRE_HOME and JAVA_HOME
rem                   are both set, JRE_HOME is used.
rem
rem   JAVA_OPTS       (Optional) Java runtime options used when any command
rem                   is executed.
rem                   Include here and not in CATALINA_OPTS all options, that
rem                   should be used by Tomcat and also by the stop process,
rem                   the version command etc.
rem                   Most options should go into CATALINA_OPTS.
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                   This is only supported for Java <= 8.
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 localhost: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   JSSE_OPTS       (Optional) Java runtime options used to control the TLS
rem                   implementation when JSSE is used. Default is:
rem                   "-Djdk.tls.ephemeralDHKeySize=2048"
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 ---------------------------------------------------------------------------

setlocal

rem Suppress Terminate batch job on CTRL+C
rem 如果执行该脚本时第一个参数(%1 表示命令之后的第一个参数,
rem 如果是用startup.bat调用的那第一个参数就是start) 不是run ,则跳转到mainEntry
if not ""%1"" == ""run"" goto mainEntry
rem %TEMP% 是系统的一个一个默认的环境变量,默认是: C:\Users\用户名\AppData\Local\Temp
rem 这里%TEMP%一般不是为空的
if "%TEMP%" == "" goto mainEntry
rem 批处理文件中 %0 表示这个可执行程序的名称, %~nx0 的话就是程序的名称+扩展名
rem 这里的 %~nx0就是指当前的程序和扩展名:catalina.bat 
rem 判断在TEMP下面是否存在 catalina.bat.run
if exist "%TEMP%%~nx0.run" goto mainEntry
rem 将字符 Y 写入到 catalina.bat.run 文件中
echo Y>"%TEMP%%~nx0.run"
rem 判断%TEMP%\catalina.bat.run 文件是否存在
if not exist "%TEMP%%~nx0.run" goto mainEntry
rem 将字符 Y 写入到%TEMP%\catalina.bat.Y 如果文件不存在, 则新建一个
echo Y>"%TEMP%%~nx0.Y"
rem "%~f0" : 表示当前命令的绝对路径.
rem "%*" : 我们知道 %1 表示第一个参数, 依次类推, %2 表示第二个.... 那么 %* 就很好理解了, 代表所有参数
rem 这里call 就是调用自身并且把所有参数都加上
call "%~f0" %* <"%TEMP%%~nx0.Y"
rem 得到上一条命令(call命令)执行后的结果码,赋值给 RETVAL
set RETVAL=%ERRORLEVEL%
rem ">" 表示输出
rem >NUL : 表示将输出重定向到 NUL 中, 你什么也看不到
rem 2>&1 : 2:错误输出, &1: 标准输出, 意思就是将错误消息输出到标准输出中.
rem >NUL 2>&1 : 就是先将错误消息输出到标准输出中, 然后再输出到 NUL 中
rem del 命令, 很容易联想到 delete, 那么 /Q 是什么意思呢? 静默删除, 不会给你任何提示,
rem 这里就是删除%TEMP%\catalina.bat.Y 这个文件
del /Q "%TEMP%%~nx0.Y" >NUL 2>&1
rem 退出当前批处理, /B 指定退出时的编号, 把 RETVAL 最为 退出码, 也就是 call 执行的命令 的退出码
exit /B %RETVAL%
rem 定义一个 mainEntry 标签, 然后删除 临时目录中的 catalina.bat.run 文件
:mainEntry
del /Q "%TEMP%%~nx0.run" >NUL 2>&1

rem 下面这一段主要是做了两件事:
rem 1. 如果环境变量 "CATALINA_HOME"不存在,则设置环境变量 %CATALINA_HOME% = 当前程序的绝对路径
rem 2. 如果环境变量 "CATALINA_BASE"不存在,则设置环境变量 %CATALINA_BASE% = %CATALINA_HOME%
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
rem 顺便做了校验 %CATALINA_HOME%\bin\catalina.bat 是否存在,如果不存在则打印异常并退出
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 Copy CATALINA_BASE from CATALINA_HOME if not defined
rem 如果 CATALINA_BASE 环境变量未设置则复制CATALINA_HOME的值
if not "%CATALINA_BASE%" == "" goto gotBase
set "CATALINA_BASE=%CATALINA_HOME%"
:gotBase

rem Ensure that neither CATALINA_HOME nor CATALINA_BASE contains a semi-colon
rem as this is used as the separator in the classpath and Java provides no
rem mechanism for escaping if the same character appears in the path. Check this
rem by replacing all occurrences of ';' with '' and checking that neither
rem CATALINA_HOME nor CATALINA_BASE have changed
rem 上面的内容翻译过来大致为:确保CATALINA_HOME 和 CATALINA_BASE 是否包含分隔符";",
rem 如果路径中出现相同的字符,Java不提供转义机制,应该先检查两个环境变量并将其中的";"替换为 ""(空)
rem 然后再次检查CATALINA_HOME CATALINA_BASE 是否已经修改

rem 如果 CATALINA_HOME 中存在 ";" 保错,程序结束
if "%CATALINA_HOME%" == "%CATALINA_HOME:;=%" goto homeNoSemicolon
echo Using CATALINA_HOME:   "%CATALINA_HOME%"
echo Unable to start as CATALINA_HOME contains a semicolon (;) character
goto end
:homeNoSemicolon
rem 如果 CATALINA_BASE 中存在 ";" 保错,程序结束
if "%CATALINA_BASE%" == "%CATALINA_BASE:;=%" goto baseNoSemicolon
echo Using CATALINA_BASE:   "%CATALINA_BASE%"
echo Unable to start as CATALINA_BASE contains a semicolon (;) character
goto end
:baseNoSemicolon

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.
rem 确保在启动是不是用用户定义的类路径,但是在极少数情况下允许在 setenv.bat 中指定

rem 定义 CLASSPATH 变量
set CLASSPATH=

rem Get standard environment variables
rem 如果 CATALINA_BASE 路径下 不存在 setenv.bat 文件,则跳到 checkSetenvHome
if not exist "%CATALINA_BASE%\bin\setenv.bat" goto checkSetenvHome
rem 如果存在 setenv.bat 文件,则执行(call) setenv 脚本文件
call "%CATALINA_BASE%\bin\setenv.bat"
goto setenvDone
:checkSetenvHome
rem 如果 CATALINA_HOME 路径下 存在 setenv.bat 文件,则执行(call) setenv 脚本文件
if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat"
:setenvDone

rem Get standard Java environment variables
rem 如果 CATALINA_HOME 路径下存在 setclasspath.bat 文件,则跳到 okSetclasspath
if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath
rem 如果不存在 setclasspath.bat 保错并结束启动程序
echo Cannot find "%CATALINA_HOME%\bin\setclasspath.bat"
echo This file is needed to run this program
goto end
:okSetclasspath
rem 如果存在 setclasspath.bat 文件,则执行(call) setclasspath 脚本文件,并且还要带上第一个参数
rem 如果是用startup.bat调用的那第一个参数就是 start
call "%CATALINA_HOME%\bin\setclasspath.bat" %1
rem 如果上面的执行 setclasspath.bat 的返回值为空1的话直接跳转到 end 标签
if errorlevel 1 goto end

rem 执行到这里之后已经设置好了 CLASSPATH 的值了

rem Add on extra jar file to CLASSPATH
rem 将额外的jar添加到CLASSPATH上
rem Note that there are no quotes as we do not want to introduce random
rem quotes into the CLASSPATH
rem 请注意,没有引号,因为我们不想在类路径中引入随机引号

rem 如果 CLASSPATH 为空,则跳转到  标签
if "%CLASSPATH%" == "" goto emptyClasspath
rem 如果不为空 将环境变量中 %CLASSPATH% 赋值给临时变量 CLASSPATH 
set "CLASSPATH=%CLASSPATH%;"
:emptyClasspath
rem 给 CLASSPATH 赋值: %CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar 
rem 实际就是给现有的CLASSPATH上再拼接上 bootstrap.jar 的绝对路径
set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar"
rem 如果 环境变量 CATALINA_TMPDIR 为空的话,将其置为:%CATALINA_BASE%\temp
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
rem 将Tomcat bin 目录下的 tomcat-juli.jar 添加到CLASSPATH中
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

rem 如果 环境变量 JSSE_OPTS 为空的话,设值为:-Djdk.tls.ephemeralDHKeySize=2048
if not "%JSSE_OPTS%" == "" goto gotJsseOpts
set JSSE_OPTS="-Djdk.tls.ephemeralDHKeySize=2048"
:gotJsseOpts
rem 将 JAVA_OPTS 和 JSSE_OPTS 两个变量赋值给 JAVA_OPTS
set "JAVA_OPTS=%JAVA_OPTS% %JSSE_OPTS%"

rem Register custom URL handlers
rem Do this here so custom URL handles (specifically 'war:...') can be used in the security policy
rem 给 JAVA—_OPTS  继续拼接参数
set "JAVA_OPTS=%JAVA_OPTS% -Djava.protocol.handler.pkgs=org.apache.catalina.webresources"
rem 如果 环境变量 LOGGING_CONFIG 为空的话,设值为:-Dnop
if not "%LOGGING_CONFIG%" == "" goto noJuliConfig
set LOGGING_CONFIG=-Dnop
rem 如果存在 %CATALINA_BASE%\conf\logging.properties,给 LOGGING_CONFIG 设值
if not exist "%CATALINA_BASE%\conf\logging.properties" goto noJuliConfig
set LOGGING_CONFIG=-Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties"
:noJuliConfig

rem 给 LOGGING_MANAGER 设值
if not "%LOGGING_MANAGER%" == "" goto noJuliManager
set LOGGING_MANAGER=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
:noJuliManager

rem Java 9 no longer supports the java.endorsed.dirs
rem system property. Only try to use it if
rem JAVA_ENDORSED_DIRS was explicitly set
rem or CATALINA_HOME/endorsed exists.
set ENDORSED_PROP=ignore.endorsed.dirs
if "%JAVA_ENDORSED_DIRS%" == "" goto noEndorsedVar
set ENDORSED_PROP=java.endorsed.dirs
goto doneEndorsed
:noEndorsedVar
if not exist "%CATALINA_HOME%\endorsed" goto doneEndorsed
set ENDORSED_PROP=java.endorsed.dirs
:doneEndorsed

rem Configure JAVA 9 specific start-up parameters
set "JDK_JAVA_OPTIONS=%JDK_JAVA_OPTIONS% --add-opens=java.base/java.lang=ALL-UNNAMED"
set "JDK_JAVA_OPTIONS=%JDK_JAVA_OPTIONS% --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED"

rem ----- Execute The Requested Command ---------------------------------------
rem 打印环境变量
echo Using CATALINA_BASE:   "%CATALINA_BASE%"
echo Using CATALINA_HOME:   "%CATALINA_HOME%"
echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%"
rem 这里可以看到参数还支持:debug 
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%"

rem _RUNJAVA : %JRE_HOME%\bin\java.exe java启动类(jvm启动类)
set _EXECJAVA=%_RUNJAVA%
rem MAINCLASS : 指定了 Tomcat 的启动类, 没错 main 方法就是在这个 Bootstrap 里面
set MAINCLASS=org.apache.catalina.startup.Bootstrap
rem ACTION : 动作: 就是启动
set ACTION=start
rem SECURITY_POLICY_FILE : 安全策略文件, 如果启动的时候加上了 -security 参数的话, 下面会对这个参数指定到 Tomcat 的 conf 目录下的 catalina.policy 文件
set SECURITY_POLICY_FILE=
set DEBUG_OPTS=
set JPDA=

rem 这里可以看到参数还支持:jpda
rem Tomcat开启Jpda支持(远程调试)
rem 默认情况下tomcat的启动命令是: ./catalina.sh start 该命令是没有启动我们的jpda服务。
rem tomcat提供了集成了Jpda服务,只需要: ./catalina.sh jpda start 这样就启动了我们服务器jvm的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
rem tomcat默认的jpda服务的端口是8000,这里可以修改
set JPDA_ADDRESS=localhost: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

rem 这里看到启动是可以添加的参数
if ""%1"" == ""debug"" goto doDebug
if ""%1"" == ""run"" goto doRun
if ""%1"" == ""start"" goto doStart
if ""%1"" == ""stop"" goto doStop
if ""%1"" == ""configtest"" goto doConfigTest
if ""%1"" == ""version"" goto doVersion

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   configtest        Run a basic syntax check on server.xml
echo   version           What version of tomcat are you running?
goto end

: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 "%TITLE%" == "" set TITLE=Tomcat
set _EXECJAVA=start "%TITLE%" %_RUNJAVA%
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
goto execCmd

rem  start 和 run 的启动区别.
rem 可以看到,strat 比 run 多了一下两行代码:
rem if "%TITLE%" == "" set TITLE=Tomcat
rem set _EXECJAVA=start "%TITLE%" %_RUNJAVA%
rem 如果是 startup.bat 脚本启动的话, 会启动一个新的 cmd 窗口, 并且把 cmd 的 title 设置为 Tomcat.
rem 如果是 catalina.bat run 启动的话, 不会新建 cmd 窗口, 也不会设置 cmd 的 title.

:doStop
shift
set ACTION=stop
set CATALINA_OPTS=
goto execCmd

:doConfigTest
shift
set ACTION=configtest
set CATALINA_OPTS=
goto execCmd



:doVersion
%_EXECJAVA% -classpath "%CATALINA_HOME%\lib\catalina.jar" org.apache.catalina.util.ServerInfo
goto end
rem shift 上面可以理解为一个switch语句块,根据不同的参数执行对应的代码块
rem shift 可以理解为一个移位命令,%1 默认取第一个参数,使用一次shifthou  %1就取第二个参数了
rem 第二个shift 是在移除掉一个参数

:execCmd
rem Get remaining unshifted command line arguments and save them in the
set CMD_LINE_ARGS=
:setArgs
rem 此时 %1 如果前面已经使用了两次shift 则此处就是取第三个参数了 
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs

rem Execute Java with the applicable properties
rem 判断启动模式是否为 JPDA (远程调试)
if not "%JPDA%" == "" goto doJpda
if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity
rem 下面这段长命令就是来启动 BootStrap 类, 并把相应的参数传进去.
rem 只要把对应的环境变量替换为它们的值, 就可以解析出这个长命令的内容
rem %_EXECJAVA%                                "D:\Program Files\Java\jdk1.8.0_101\bin\java.exe" 
rem %LOGGING_CONFIG%                           -Djava.util.logging.config.file="D:\tools\tomcat\conf\logging.properties" 
rem %LOGGING_MANAGER%                          -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 
rem %JAVA_OPTS%                                "-Djdk.tls.ephemeralDHKeySize=2048"
rem %CATALINA_OPTS%                            
rem %DEBUG_OPTS%                               -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 
rem -D%ENDORSED_PROP%="%JAVA_ENDORSED_DIRS%"   -Dignore.endorsed.dirs="" 
rem -classpath "%CLASSPATH%"                   -classpath "D:\tools\tomcat\bin\bootstrap.jar;D:\tools\tomcat\bin\tomcat-juli.jar"
rem -Dcatalina.base="%CATALINA_BASE%"          -Dcatalina.base="D:\tools\tomcat" 
rem -Dcatalina.home="%CATALINA_HOME%"          -Dcatalina.home="D:\tools\tomcat" 
rem -Djava.io.tmpdir="%CATALINA_TMPDIR%"       -Djava.io.tmpdir="D:\tools\tomcat\temp"
rem %MAINCLASS%                                org.apache.catalina.startup.Bootstrap
rem %CMD_LINE_ARGS% 
rem %ACTION%                                   start
%_EXECJAVA% %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%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% %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%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% %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %JPDA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%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% %LOGGING_CONFIG% %LOGGING_MANAGER% %JAVA_OPTS% %JPDA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -D%ENDORSED_PROP%="%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