这个批处理才是tomcat服务器启动跟关闭的核心脚本。其中包括。。。。(各种变量),此节将详细讲解这个批处理的逻辑。

先看看第一部分脚本:

********************************************************************************************

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"

set RETVAL=%ERRORLEVEL%

del /Q "%TEMP%\%~nx0.Y" >NUL 2>&1

exit /B %RETVAL%

:mainEntry

del /Q "%TEMP%\%~nx0.run" >NUL 2>&1

********************************************************************************************

第一行判断如果%1即第一个参数等于run则直接跳到mainEntry,使用两个双引号是为了防止参数中带有空格;第二行判断TEMP环境变量为空的话则直接跳到mainEntry;第三行判断如果TEMP环境变量目录下存在catalina.bat.run文件则直接跳到mainEntry;第四行把字母Y输入catalina.bat.run文件中;第五行判断如果不存在catalina.bat.run文件则跳到mainEntry;第六行将字母Y输入到catalina.bat.Y文件中;第七行以catalina.bat.Y作为输入执行当前批处理,%*表示所有的参数;第八行把上面执行后的%ERRORLEVEL%变量赋值给RETVAL,如果执行过程出现问题则为非零值;第九行删除catalina.bat.Y文件,并且不输出执行结果,另外把标准错误输出STDERR重定向到标准输出STDOUT;第十行退出当前批处理脚本,并把RETVAL变量作为返回值。剩下两行脚本不再赘述。

第二部分脚本主要是设置CATALINA_HOME、CATALINA_BASE两个变量。

********************************************************************************************

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

goto end

:okHome

if not "%CATALINA_BASE%" == "" goto gotBase

set "CATALINA_BASE=%CATALINA_HOME%"

:gotBase

********************************************************************************************

设置CATALINA_HOME环境变量,逻辑跟startup.bat的一样,这里为什么还要进行一次CATALINA_HOME环境变量设置呢?简单地说,是为了支持用户直接运行catalina.bat,而非通过startup.bat运行。接着设置CATALINA_BASE环境变量,这里直接把CATALINA_HOME的值赋给它了。

第三部分脚本主要是设置CLASSPATH环境变量,把各种需要的jar包添加到CLASSPATH下。

********************************************************************************************

set CLASSPATH= 

if not exist "%CATALINA_BASE%\bin\setenv.bat" goto checkSetenvHome

call "%CATALINA_BASE%\bin\setenv.bat"

goto setenvDone

:checkSetenvHome

if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat"

:setenvDone

if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath

goto end

:okSetclasspath

call "%CATALINA_HOME%\bin\setclasspath.bat" %1

if errorlevel 1 goto end

if "%CLASSPATH%" == "" goto emptyClasspath

set "CLASSPATH=%CLASSPATH%;"

:emptyClasspath

set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar"

if not "%CATALINA_TMPDIR%" == "" goto gotTmpdir

set "CATALINA_TMPDIR=%CATALINA_BASE%\temp"

:gotTmpdir

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

********************************************************************************************

把CLASSPATH设为空,判断%CATALINA_BASE%\bin目录下是否存在setenv.bat,如果存在则调用此批处理文件,否则判断%CATALINA_HOME%\bin目录下是否存在setenv.bat,如存在则执行;往下继续判断是否存在%CATALINA_HOME%\bin\setclasspath.bat文件,这里如果不存在则直接跳到结尾,表明这个setclasspath.bat是必要的批处理脚本,接着执行setclasspath.bat脚本,%1表示参数。if errorlevel 1 goto
end表示执行到此如果错误值大于等于1则直接跳到结尾,如果没有错误,则继续往下,判断环境变量%CLASSPATH%是否为空,不为空则把CLASSPATH设置为%CLASSPATH%并加上分号,此后把%CATALINA_HOME%\bin\bootstrap.jar加入到classpath中,这个包是tomcat的内核。紧接着设置临时目录temp,追加tomcat-juli.jar包到classpath中,基本逻辑是先从%CATALINA_BASE%\bin目录下找,不存在的话再去%CATALINA_HOME%\bin目录下找。tomcat-juli.jar这个包主要包含tomcat系统日志处理类,详情请重温第三部分的第四节——日志框架。

第四部分是对日志配置的设置。

********************************************************************************************

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%

********************************************************************************************

Tomcat中的日志实现是用jdk自带的日志工具类,其中主要有两项属性可以配置,分别为java.util.logging.config.file跟java.util.logging.manager,首先判断环境变量是否存在LOGGING_CONFIG,存在即直接使用,否则把LOGGING_CONFIG设为-Dnop,并且往下判断是否存在%CATALINA_BASE%\conf\logging.properties,如存在则又把LOGGING_CONFIG设为-Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties"。特别说明一下set
JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%,你会发现原版的脚步前面即没有JAVA_OPTS这个变量,也没有JAVA_OPTS这个环境变量,这样做的目的是为了把所有参数都能追加到JAVA_OPTS上,比如运维人员在前面已经有了JAVA_OPTS这个变量,执行到此便会追加到JAVA_OPTS后面,假如前面没有JAVA_OPTS变量则作为空值,不影响运行。对于LOGGING_MANAGER变量的设置跟LOGGING_CONFIG同一个道理。

第五部分是执行命令前一些参数的初始化。

********************************************************************************************

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

********************************************************************************************

把%_RUNJAVA%变量赋给_EXECJAVA,%_RUNJAVA%变量在setclasspath.bat 脚本中已经被设置为%JRE_HOME%\bin\java,设置MAINCLASS为tomcat的启动类Bootstrap,ACTION为start,其他变量先不初始化。如果第一个参数为jpda,则把JPDA变量设为值jpda,jpda即是Java 平台调试体系结构,它可以提供很方便的远程调试;如果JPDA_TRANSPORT变量为空则设为dt_socket;如果JPDA_ADDRESS变量为空则设置为8000;如果JPDA_SUSPEND变量为空则设为n;如果JPDA_OPTS变量为空则设为-agentlib:jdwp=transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%。最后用了一个shift,把参数前移一位。这段主要初始化JPDA启动命令项,把JDWP代理加载到应用程序的JVM。

第六部分命令主要是根据不同的参数跳转到不同的位置执行不同命令,其实也是组装一些参数,为下一步真正执行命令做准备。

********************************************************************************************

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

:doDebug

shift

set _EXECJAVA=%_RUNJDB%

set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%\..\..\java"

if not ""%1"" == ""-security"" goto execCmd

shift

set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"

goto execCmd

:doRun

shift

if not ""%1"" == ""-security"" goto execCmd

shift

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

set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"

goto execCmd

: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

********************************************************************************************

前面已经用shift把参数前移一位,此时%1表示的参数已经是下一个参数,分别按照debug、run、start、stop、configtest、version跳到doDebug、doRun、doStart、doStop、doConfigTest、doVersion标签位置执行不同的操作。下面对这六个操作进行分析:

doDebug的逻辑是,把参数前移一位,设置_EXECJAVA变量赋为%_RUNJDB%,_RUNJDB变量在setclasspath批处理脚本已经被设置为%JAVA_HOME%\bin\jdb,设置DEBUG_OPTS变量,接着判断参数是否等于-security,即是否启动安全管理器,如果没有则直接跳到execCmd位置,否则把参数前移一位,并且设置SECURITY_POLICY_FILE变量为%CATALINA_BASE%\conf\catalina.policy,这个catalina.policy有什么作用请参考第三部分第四节安全框架内容。最后跳到execCmd位置。

doRun的逻辑是,把参数前移一位,判断是否使用安全管理器,如果不使用安全管理器则直接跳到execCmd位置,否则参数前移一位,再设置SECURITY_POLICY_FILE变量,最后跳到execCmd位置。

doStart的逻辑是,把参数前移一位,根据系统是不是Windows_NT系统设置命令窗口的标题,TITLE变量被设置为Tomcat字符串。设置_EXECJAVA变量,如果有标题则添加到启动命令中,接着判断是否使用安全管理器,把参数前移一位并设置SECURITY_POLICY_FILE,最后跳到execCmd位置。

doStop、doConfigTest的逻辑差不多,把参数前移一位,设置ACTION变量为stop、configtest,清空CATALINA_OPTS变量,跳到execCmd位置。

doVersion其实就是显示服务器的信息,直接调用%JRE_HOME%\bin目录下的 java.exe程序,%CATALINA_HOME%\lib\catalina.jar作为classpath, org.apache.catalina.util.ServerInfo作为启动类,即可输出服务器相关信息,然后结束命令。

    第七部分命令的执行。

********************************************************************************************

:execCmd

set CMD_LINE_ARGS=

:setArgs

if ""%1""=="""" goto doneSetArgs

set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1

shift

goto setArgs

:doneSetArgs

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

********************************************************************************************

首先是对参数的收集,这个在前面已经见过,这里不再赘述。接下去是根据参数的值执行不同的命令,用一个图能更清楚地描述其中的逻辑。如图3-2-1-2,主要是用JPDA、SECURITY_POLICY_FILE两个变量进行判断,分别代表是否使用Java平台调试体系结构跟安全管理器。这样的话就能组成四种不同的命令,往下看看最全面的命令的详细信息:

 

图3-2-1-2

    如果既使用安全管理器又使用Java平台调试体系来启动,则会跳到doSecurityJpda位置,此时

%_EXECJAVA%为:start "Tomcat" "D:\java\jdk\bin\java"(假设java安装路径为D:\java\jdk)。

%JAVA_OPTS%为:-Djava.util.logging.config.file="D:\java\apache-tomcat-7.0.39\conf\logging.properties" -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager。

%CATALINA_OPTS%为:空。

%JPDA_OPTS%为:-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n。

%DEBUG_OPTS%为:空。

%JAVA_ENDORSED_DIRS%为:"D:\apache-tomcat\endorsed"(假设tomcat安装目录为D:\apache-tomcat)。

%CLASSPATH%为:"D:\apache-tomcat\bin\bootstrap.jar;D:\apache-tomcat\bin\tomcat-juli.jar"。

%SECURITY_POLICY_FILE%为:D:\apache-tomcat\conf\catalina.policy。

%CATALINA_BASE%为:D:\apache-tomcat。

%CATALINA_HOME%为:D:\apache-tomcat。

%CATALINA_TMPDIR%为:D:\apache-tomcat\temp。

%MAINCLASS%为:org.apache.catalina.startup.Bootstrap。

%CMD_LINE_ARGS%为:空。

%ACTION%为:start。

将以上的变量值组装成一个命令行就是最终启动的脚本了。

喜欢研究java的同学可以交个朋友,下面是本人的微信号:

tomcat启动批处理——catalina.bat的更多相关文章

  1. [Tomcat 源码分析系列] (二) : Tomcat 启动脚本-catalina.bat

    概述 Tomcat 的三个最重要的启动脚本: startup.bat catalina.bat setclasspath.bat 上一篇咱们分析了 startup.bat 脚本 这一篇咱们来分析 ca ...

  2. tomcat启动批处理——startup.bat

    从文件命名上看就知道这是一个启动批处理,这个批处理的主要功能就是为了找到另一个批处理catalina.bat,并且执行catalina.bat. 一开始就用if "%OS%" == ...

  3. tomcat启动批处理——setclasspath.bat

    除了上面两个批处理,还有一个比较重要的脚本,即是setclasspath.bat,它主要负责寻找.检查JAVA_HOME和JRE_HOME两个变量. ************************* ...

  4. tomcat启动(一)startup.bat|catalina.bat分析

    环境:windows X64位 Tomcat8.0.47 bootstrap.jar是tomcat的内核 开始位置 startup.bat 查看文本 具体的批处理脚本语法可以查看我整理的文章 http ...

  5. [Tomcat 源码分析系列] (一) : Tomcat 启动脚本-startup.bat

    概述 我们通常使用 Tomcat 中的 startup.bat 来启动 Tomcat. 但是这其中干了一些什么事呢? 大家都知道一个 Java 程序需要启动的话, 肯定需要 main 方法, 那么这个 ...

  6. Tomcat启动脚本catalina.sh

    1 - 概述脚本catalina.sh用于启动和关闭tomcat服务器,是最关键的脚本另外的脚本startup.sh和shutdown.sh都是使用不同的参数调用了该脚本该脚本的使用方法如下(引自该脚 ...

  7. tomcat启动(六)Catalina分析-StandardServer.start()

    从链接 Tomcat中组件的生命周期管理公共接口Lifecycle 可以知道调用的是StandardServer.startInternal() @Override protected void st ...

  8. tomcat启动(三)Catalina简要分析

    上篇解析Bootstrap到 daemon.setAwait(true); daemon.load(args); daemon.start(); 这三个方法实际是反射调用org.apache.cata ...

  9. tomcat启动(五)Catalina分析-service.init

    上篇写到StandardService.init() 这个方法做什么呢?一起来看看. 这个类也是实现了Lifecycle 如图.这个图中i表示Interface接口.如Lifecycle,Contai ...

随机推荐

  1. [Cqoi2010]扑克牌

    Description 你有n种牌,第i种牌的数目为ci.另外有一种特殊的 牌:joker,它的数目是m.你可以用每种牌各一张来组成一套牌,也可以用一张joker和除了某一种牌以外的其他牌各一张组成1 ...

  2. 51nod 1981 如何愉快地与STL玩耍

    Description 驴蛋蛋在愉快地与STL玩耍 突然间小A跳了出来对驴蛋蛋说,看你与STL玩的很开心啊,那我给你一个大小为N的vector,这个vector上每个位置上是一个set, 每次我会在闭 ...

  3. VK Cup 2017 - Квалификация 1

    CF上的VK Cup 2017资格赛1,好像很水,因为只有俄文所以语言是最大的障碍--不过之后正式赛貌似就有英文了.(比赛貌似只有开俄文模式才看的到--) 时长1天,不随时间扣分.FallDream ...

  4. ●BZOJ 3129 [Sdoi2013]方程

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3129 题解: 容斥,扩展Lucas,中国剩余定理 先看看不管限制,只需要每个位置都是正整数时 ...

  5. hdu 1133 Buy the Ticket(Catalan)

    Buy the Ticket Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) T ...

  6. [bzoj4824][Cqoi2017]老C的键盘

    来自FallDream的博客,未经允许,请勿转载,谢谢. 老 C 是个程序员.     作为一个优秀的程序员,老 C 拥有一个别具一格的键盘,据说这样可以大幅提升写程序的速度,还能让写出来的程序在某种 ...

  7. bzoj3894

    转载自http://www.cnblogs.com/rausen 3894: 文理分科 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1338  So ...

  8. return、break和continue

    return.break和continue 这三个关键字有一个共同点,那就是读能让后面的语句不执行,不同的地方就是挑的距离不一样. return很强大,如果一个函数中有一个return,并且执行了,那 ...

  9. 批量录入快递地址-快宝地址服务(PHP代码示例)

    快递地址写错了怎么办?快递地址写的不详细怎么办?怎么皮批量录入收件人地址?微商怎么批量录入发件人地址?快宝地址清洗,有效的解决了寄送快递时,批量录入收件人信息.发件人信息时,纠正地址数据,不完整地址识 ...

  10. CSharpGL(48)用ShadowVolume画模型的影子

    CSharpGL(48)用ShadowVolume画模型的影子 在Per-Fragment Operations & Tests阶段,有一个步骤是模版测试(Stencil Test).依靠这一 ...