查看tomcat啓動文件都乾點啥---catalina.bat

   在上一次查看tomcat啓動文件都乾點啥一文中,咱們總結出,startup.bat文件的做用就是找到catalina.bat文件,而後把參數傳遞給它,在startup.bat中,調用catalina.bat的命令call "%EXECUTABLE%" start %CMD_LINE_ARGS%,其中"%EXECUTABLE%"這個就是catalina.bat文件,這個命令至少向catalina.bat傳遞一個參數--start.html

      接下來看一下catalina.bat中的內容,內容很長:java

  1 @echo off
  2 rem Licensed to the Apache Software Foundation (ASF) under one or more
  3 rem contributor license agreements.  See the NOTICE file distributed with
  4 rem this work for additional information regarding copyright ownership.
  5 rem The ASF licenses this file to You under the Apache License, Version 2.0
  6 rem (the "License"); you may not use this file except in compliance with
  7 rem the License.  You may obtain a copy of the License at
  8 rem
  9 rem     http://www.apache.org/licenses/LICENSE-2.0
 10 rem
 11 rem Unless required by applicable law or agreed to in writing, software
 12 rem distributed under the License is distributed on an "AS IS" BASIS,
 13 rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14 rem See the License for the specific language governing permissions and
 15 rem limitations under the License.
 16 
 17 if "%OS%" == "Windows_NT" setlocal
 18 rem ---------------------------------------------------------------------------
 19 rem Start/Stop Script for the CATALINA Server
 20 rem
 21 rem Environment Variable Prerequisites
 22 rem
 23 rem   CATALINA_HOME   May point at your Catalina "build" directory.
 24 rem
 25 rem   CATALINA_BASE   (Optional) Base directory for resolving dynamic portions
 26 rem                   of a Catalina installation.  If not present, resolves to
 27 rem                   the same directory that CATALINA_HOME points to.
 28 rem
 29 rem   CATALINA_OPTS   (Optional) Java runtime options used when the "start",
 30 rem                   or "run" command is executed.
 31 rem
 32 rem   CATALINA_TMPDIR (Optional) Directory path location of temporary directory
 33 rem                   the JVM should use (java.io.tmpdir).  Defaults to
 34 rem                   %CATALINA_BASE%\temp.
 35 rem
 36 rem   JAVA_HOME       Must point at your Java Development Kit installation.
 37 rem                   Required to run the with the "debug" argument.
 38 rem
 39 rem   JRE_HOME        Must point at your Java Runtime installation.
 40 rem                   Defaults to JAVA_HOME if empty.
 41 rem
 42 rem   JAVA_OPTS       (Optional) Java runtime options used when the "start",
 43 rem                   "stop", or "run" command is executed.
 44 rem
 45 rem   JAVA_ENDORSED_DIRS (Optional) Lists of of semi-colon separated directories
 46 rem                   containing some jars in order to allow replacement of APIs 
 47 rem                   created outside of the JCP (i.e. DOM and SAX from W3C). 
 48 rem                   It can also be used to update the XML parser implementation.
 49 rem                   Defaults to $CATALINA_HOME/endorsed.
 50 rem
 51 rem   JPDA_TRANSPORT  (Optional) JPDA transport used when the "jpda start"
 52 rem                   command is executed. The default is "dt_socket".
 53 rem
 54 rem   JPDA_ADDRESS    (Optional) Java runtime options used when the "jpda start"
 55 rem                   command is executed. The default is 8000.
 56 rem
 57 rem   JPDA_SUSPEND    (Optional) Java runtime options used when the "jpda start"
 58 rem                   command is executed. Specifies whether JVM should suspend
 59 rem                   execution immediately after startup. Default is "n".
 60 rem
 61 rem   JPDA_OPTS       (Optional) Java runtime options used when the "jpda start"
 62 rem                   command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,
 63 rem                   and JPDA_SUSPEND are ignored. Thus, all required jpda
 64 rem                   options MUST be specified. The default is:
 65 rem
 66 rem                   -agentlib:jdwp=transport=%JPDA_TRANSPORT%,
 67 rem                       address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%
 68 rem
 69 rem   LOGGING_CONFIG  (Optional) Override Tomcat's logging config file
 70 rem                   Example (all one line)
 71 rem                   set LOGGING_CONFIG="-Djava.util.logging.config.file=%CATALINA_BASE%\conf\logging.properties"
 72 rem
 73 rem   LOGGING_MANAGER (Optional) Override Tomcat's logging manager 
 74 rem                   Example (all one line)
 75 rem                   set LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
 76 rem
 77 rem   TITLE           (Optional) Specify the title of Tomcat window. The default
 78 rem                   TITLE is Tomcat if it's not specified.
 79 rem                   Example (all one line)
 80 rem                   set TITLE=Tomcat.Cluster#1.Server#1 [%DATE% %TIME%]
 81 rem
 82 rem
 83 rem
 84 rem $Id: catalina.bat 1040546 2010-11-30 14:47:34Z markt $
 85 rem ---------------------------------------------------------------------------
 86 
 87 rem Suppress Terminate batch job on CTRL+C
 88 if not ""%1"" == ""run"" goto mainEntry
 89 if ""%TEMP%"" == """" goto mainEntry
 90 if exist "%TEMP%\%~nx0.run" goto mainEntry
 91 echo Y>"%TEMP%\%~nx0.run"
 92 if not exist "%TEMP%\%~nx0.run" goto mainEntry
 93 echo Y>"%TEMP%\%~nx0.Y"
 94 call "%~f0" %* <"%TEMP%\%~nx0.Y"
 95 rem Use provided errorlevel
 96 set RETVAL=%ERRORLEVEL%
 97 del /Q "%TEMP%\%~nx0.Y" >NUL 2>&1
 98 exit /B %RETVAL%
 99 :mainEntry
100 del /Q "%TEMP%\%~nx0.run" >NUL 2>&1
101 
102 rem Guess CATALINA_HOME if not defined
103 set "CURRENT_DIR=%cd%"
104 if not "%CATALINA_HOME%" == "" goto gotHome
105 set "CATALINA_HOME=%CURRENT_DIR%"
106 if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
107 cd ..
108 set "CATALINA_HOME=%cd%"
109 cd "%CURRENT_DIR%"
110 :gotHome
111 if exist "%CATALINA_HOME%\bin\catalina.bat" goto okHome
112 echo The CATALINA_HOME environment variable is not defined correctly
113 echo This environment variable is needed to run this program
114 goto end
115 :okHome
116 
117 rem Ensure that any user defined CLASSPATH variables are not used on startup,
118 rem but allow them to be specified in setenv.bat, in rare case when it is needed.
119 set CLASSPATH=
120 
121 rem Get standard environment variables
122 if "%CATALINA_BASE%" == "" goto gotSetenvHome
123 if exist "%CATALINA_BASE%\bin\setenv.bat" call "%CATALINA_BASE%\bin\setenv.bat"
124 goto gotSetenvBase
125 :gotSetenvHome
126 if exist "%CATALINA_HOME%\bin\setenv.bat" call "%CATALINA_HOME%\bin\setenv.bat"
127 :gotSetenvBase
128 
129 rem Get standard Java environment variables
130 if exist "%CATALINA_HOME%\bin\setclasspath.bat" goto okSetclasspath
131 echo Cannot find "%CATALINA_HOME%\bin\setclasspath.bat"
132 echo This file is needed to run this program
133 goto end
134 :okSetclasspath
135 set "BASEDIR=%CATALINA_HOME%"
136 call "%CATALINA_HOME%\bin\setclasspath.bat" %1
137 if errorlevel 1 goto end
138 
139 rem Add on extra jar file to CLASSPATH
140 rem Note that there are no quotes as we do not want to introduce random
141 rem quotes into the CLASSPATH
142 if "%CLASSPATH%" == "" goto emptyClasspath
143 set "CLASSPATH=%CLASSPATH%;"
144 :emptyClasspath
145 set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar"
146 
147 if not "%CATALINA_BASE%" == "" goto gotBase
148 set "CATALINA_BASE=%CATALINA_HOME%"
149 :gotBase
150 
151 if not "%CATALINA_TMPDIR%" == "" goto gotTmpdir
152 set "CATALINA_TMPDIR=%CATALINA_BASE%\temp"
153 :gotTmpdir
154 
155 rem Add tomcat-juli.jar to classpath
156 rem tomcat-juli.jar can be over-ridden per instance
157 if not exist "%CATALINA_BASE%\bin\tomcat-juli.jar" goto juliClasspathHome
158 set "CLASSPATH=%CLASSPATH%;%CATALINA_BASE%\bin\tomcat-juli.jar"
159 goto juliClasspathDone
160 :juliClasspathHome
161 set "CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\bin\tomcat-juli.jar"
162 :juliClasspathDone
163 
164 if not "%LOGGING_CONFIG%" == "" goto noJuliConfig
165 set LOGGING_CONFIG=-Dnop
166 if not exist "%CATALINA_BASE%\conf\logging.properties" goto noJuliConfig
167 set LOGGING_CONFIG=-Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties"
168 :noJuliConfig
169 set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%
170 
171 if not "%LOGGING_MANAGER%" == "" goto noJuliManager
172 set LOGGING_MANAGER=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
173 :noJuliManager
174 set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%
175 
176 rem ----- Execute The Requested Command ---------------------------------------
177 
178 echo Using CATALINA_BASE:   "%CATALINA_BASE%"
179 echo Using CATALINA_HOME:   "%CATALINA_HOME%"
180 echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%"
181 if ""%1"" == ""debug"" goto use_jdk
182 echo Using JRE_HOME:        "%JRE_HOME%"
183 goto java_dir_displayed
184 :use_jdk
185 echo Using JAVA_HOME:       "%JAVA_HOME%"
186 :java_dir_displayed
187 echo Using CLASSPATH:       "%CLASSPATH%"
188 
189 set _EXECJAVA=%_RUNJAVA%
190 set MAINCLASS=org.apache.catalina.startup.Bootstrap
191 set ACTION=start
192 set SECURITY_POLICY_FILE=
193 set DEBUG_OPTS=
194 set JPDA=
195 
196 if not ""%1"" == ""jpda"" goto noJpda
197 set JPDA=jpda
198 if not "%JPDA_TRANSPORT%" == "" goto gotJpdaTransport
199 set JPDA_TRANSPORT=dt_socket
200 :gotJpdaTransport
201 if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress
202 set JPDA_ADDRESS=8000
203 :gotJpdaAddress
204 if not "%JPDA_SUSPEND%" == "" goto gotJpdaSuspend
205 set JPDA_SUSPEND=n
206 :gotJpdaSuspend
207 if not "%JPDA_OPTS%" == "" goto gotJpdaOpts
208 set JPDA_OPTS=-agentlib:jdwp=transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%
209 :gotJpdaOpts
210 shift
211 :noJpda
212 
213 if ""%1"" == ""debug"" goto doDebug
214 if ""%1"" == ""run"" goto doRun
215 if ""%1"" == ""start"" goto doStart
216 if ""%1"" == ""stop"" goto doStop
217 if ""%1"" == ""version"" goto doVersion
218 
219 echo Usage:  catalina ( commands ... )
220 echo commands:
221 echo   debug             Start Catalina in a debugger
222 echo   debug -security   Debug Catalina with a security manager
223 echo   jpda start        Start Catalina under JPDA debugger
224 echo   run               Start Catalina in the current window
225 echo   run -security     Start in the current window with security manager
226 echo   start             Start Catalina in a separate window
227 echo   start -security   Start in a separate window with security manager
228 echo   stop              Stop Catalina
229 echo   version           What version of tomcat are you running?
230 goto end
231 
232 :doDebug
233 shift
234 set _EXECJAVA=%_RUNJDB%
235 set DEBUG_OPTS=-sourcepath "%CATALINA_HOME%\..\..\java"
236 if not ""%1"" == ""-security"" goto execCmd
237 shift
238 echo Using Security Manager
239 set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
240 goto execCmd
241 
242 :doRun
243 shift
244 if not ""%1"" == ""-security"" goto execCmd
245 shift
246 echo Using Security Manager
247 set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
248 goto execCmd
249 
250 :doStart
251 shift
252 if not "%OS%" == "Windows_NT" goto noTitle
253 if "%TITLE%" == "" set TITLE=Tomcat
254 set _EXECJAVA=start "%TITLE%" %_RUNJAVA%
255 goto gotTitle
256 :noTitle
257 set _EXECJAVA=start %_RUNJAVA%
258 :gotTitle
259 if not ""%1"" == ""-security"" goto execCmd
260 shift
261 echo Using Security Manager
262 set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
263 goto execCmd
264 
265 :doStop
266 shift
267 set ACTION=stop
268 set CATALINA_OPTS=
269 goto execCmd
270 
271 :doVersion
272 %_EXECJAVA% -classpath "%CATALINA_HOME%\lib\catalina.jar" org.apache.catalina.util.ServerInfo
273 goto end
274 
275 
276 :execCmd
277 rem Get remaining unshifted command line arguments and save them in the
278 set CMD_LINE_ARGS=
279 :setArgs
280 if ""%1""=="""" goto doneSetArgs
281 set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
282 shift
283 goto setArgs
284 :doneSetArgs
285 
286 rem Execute Java with the applicable properties
287 if not "%JPDA%" == "" goto doJpda
288 if not "%SECURITY_POLICY_FILE%" == "" goto doSecurity
289 %_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%
290 goto end
291 :doSecurity
292 %_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%
293 goto end
294 :doJpda
295 if not "%SECURITY_POLICY_FILE%" == "" goto doSecurityJpda
296 %_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%
297 goto end
298 :doSecurityJpda
299 %_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%
300 goto end
301 
302 :end
View Code

在第1行,和第17行中的內容已經在前一章中作出說明,在此處再也不敖述,我對於18-85行的這段註釋比較感興趣:web

 1 rem ---------------------------------------------------------------------------
 2 rem Start/Stop Script for the CATALINA Server
 3 rem
 4 rem Environment Variable Prerequisites
 5 rem
 6 rem   CATALINA_HOME   May point at your Catalina "build" directory.
 7 rem
 8 rem   CATALINA_BASE   (Optional) Base directory for resolving dynamic portions
 9 rem                   of a Catalina installation.  If not present, resolves to
10 rem                   the same directory that CATALINA_HOME points to.
11 rem
12 rem   CATALINA_OPTS   (Optional) Java runtime options used when the "start",
13 rem                   or "run" command is executed.
14 rem
15 rem   CATALINA_TMPDIR (Optional) Directory path location of temporary directory
16 rem                   the JVM should use (java.io.tmpdir).  Defaults to
17 rem                   %CATALINA_BASE%\temp.
18 rem
19 rem   JAVA_HOME       Must point at your Java Development Kit installation.
20 rem                   Required to run the with the "debug" argument.
21 rem
22 rem   JRE_HOME        Must point at your Java Runtime installation.
23 rem                   Defaults to JAVA_HOME if empty.
24 rem
25 rem   JAVA_OPTS       (Optional) Java runtime options used when the "start",
26 rem                   "stop", or "run" command is executed.
27 rem
28 rem   JAVA_ENDORSED_DIRS (Optional) Lists of of semi-colon separated directories
29 rem                   containing some jars in order to allow replacement of APIs 
30 rem                   created outside of the JCP (i.e. DOM and SAX from W3C). 
31 rem                   It can also be used to update the XML parser implementation.
32 rem                   Defaults to $CATALINA_HOME/endorsed.
33 rem
34 rem   JPDA_TRANSPORT  (Optional) JPDA transport used when the "jpda start"
35 rem                   command is executed. The default is "dt_socket".
36 rem
37 rem   JPDA_ADDRESS    (Optional) Java runtime options used when the "jpda start"
38 rem                   command is executed. The default is 8000.
39 rem
40 rem   JPDA_SUSPEND    (Optional) Java runtime options used when the "jpda start"
41 rem                   command is executed. Specifies whether JVM should suspend
42 rem                   execution immediately after startup. Default is "n".
43 rem
44 rem   JPDA_OPTS       (Optional) Java runtime options used when the "jpda start"
45 rem                   command is executed. If used, JPDA_TRANSPORT, JPDA_ADDRESS,
46 rem                   and JPDA_SUSPEND are ignored. Thus, all required jpda
47 rem                   options MUST be specified. The default is:
48 rem
49 rem                   -agentlib:jdwp=transport=%JPDA_TRANSPORT%,
50 rem                       address=%JPDA_ADDRESS%,server=y,suspend=%JPDA_SUSPEND%
51 rem
52 rem   LOGGING_CONFIG  (Optional) Override Tomcat's logging config file
53 rem                   Example (all one line)
54 rem                   set LOGGING_CONFIG="-Djava.util.logging.config.file=%CATALINA_BASE%\conf\logging.properties"
55 rem
56 rem   LOGGING_MANAGER (Optional) Override Tomcat's logging manager 
57 rem                   Example (all one line)
58 rem                   set LOGGING_MANAGER="-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager"
59 rem
60 rem   TITLE           (Optional) Specify the title of Tomcat window. The default
61 rem                   TITLE is Tomcat if it's not specified.
62 rem                   Example (all one line)
63 rem                   set TITLE=Tomcat.Cluster#1.Server#1 [%DATE% %TIME%]
64 rem
65 rem
66 rem
67 rem $Id: catalina.bat 1040546 2010-11-30 14:47:34Z markt $
68 rem ---------------------------------------------------------------------------

這段的內容就是說明一下在啓動和中止CATALINA server時候須要的一下先決條件,CATALINA_HOME--看到這個你們可能會有點疑問,若是在操做系統上沒有設置CATALINA_HOME變量的時候,那麼這個變量應該是不存在的丫,是怎麼回事呢?是否是?下面咱們仍是用測試來講明問題:我在F:\apache-tomcat-7.0.8\bin目錄下建立一個test.bat文件,文件內容以下:    sql

@echo off
set CURRENT_DIR=%cd%
test2.bat

     意思很簡單,只是將%cd%變量的值賦給CURRENT_DIR變量,而後調用test2.bat文件,test2.bat文件的內容以下:express

echo %CURRENT_DIR%

     只是簡單的輸出%CURRENT_DIR%變量,讓咱們先運行test.bat文件,查看%CURRENT_DIR%變量是否可以正確輸出:apache

  

       結果正確顯示了,可是若是咱們直接運行test2.bat文件會有什麼結果呢?bootstrap

   

      結果顯示不正常,這個測試就說明由test.bat調用test2.bat文件時候,test.bat中定義的變量在test2.bat中可見,就是CURRENT_DIR變量的生命週期範圍並非僅限於本文件,也能加深對於setlocal方法的理解。回到catalina.bat自己,也許咱們自己沒有設置CATALINA_HOME環境變量的習慣,可是回想一下上一節,在startup.bat中說到,若是沒有設置CATALINA_HOME變量,startup.bat內會給CATALINA_HOME變量賦值,而後在catalina.bat中依然可以訪問此變量。tomcat

     這段註釋說完以後,看一下88行:      安全

if not ""%1"" == ""run"" goto mainEntry

  若是接收到的第一個參數是run那麼到:mainEntry節點,事實是咱們從startup.bat調用的時候傳遞的第一個參數無疑是start,因此應該順序執行到第89行,這裏可能有人會有疑問,那何時第一個參數纔是run呢?事情是這樣的,由於並非全部人都是跟咱們同樣直接使用startup.bat文件啓動,由於startup.bat文件也只不過就是找到catalina.bat文件,而後照樣傳遞參數,其實有經驗的人大可直接使用catalina.bat文件來啓動tomcat。這就是第一個參數爲run的產生狀況。接下來咱們順序執行到第89行。cookie

    看一下89行的內容:

if ""%TEMP%"" == """" goto mainEntry

   若是TEMP變量爲空,那麼到mainEntry節點,這個時候咱們就須要看看咱們到底有沒有這個TEMP變量,一樣弄個小測試,寫一個小的測試test.bat文件,文件內容以下:  

@echo off
echo %TEMP%

  查看執行結果:

 

      記得在上一節中說過%TEMP%這個變量是從環境變量中讀取的,因此也能夠去環境變量中查看是否是有此值,來肯定TEMP變量是否是存在,一問在startup.bat和catalina.bat並無設置TEMP變量。查看環境變量:

  

     由於TEMP存在,因此程序還須要順序執行到90行,第90行的內容以下:   

if exist "%TEMP%\%~nx0.run" goto mainEntry

  這句話至少看起來有點蒙圈,尤爲是\%~nx0.run這個東西,反正我第一次看見的時候我就想問問,這是毛啊,~nx0,下面看一下網上對於%~nx0的解釋:

%~nx0 contains the name of the running batch file (without the path)

  意思就是表明執行命令的文件的名字,咱們來用實驗證實一下,一樣仍是修改那個test.bat文件吧。;-)  

@echo off
echo "%TEMP%\%~nx0.run"

  若是按照上面的解釋,那麼輸出的信息應該是C:\Users\Think\AppData\Local\Temp\test.bat.run,下面看一下運行結果:

  

  咦事實證實說法正確,可是這個文件是否是存在呢,咱們去TEMP目錄下看一下,遺憾的是在C:\Users\Think\AppData\Local\Temp目錄沒有找到這個文件,因此還得順序執行到第91行,91行的內容是:  

echo Y>"%TEMP%\%~nx0.run"

  這個看起來很簡單,既然不存在這個文件,那麼我就本身建立一個,同時寫入Y。也許你不信,因此我仍是拿出個例子吧,仍是test.bat呦:

@echo off
echo Y>"%TEMP%\%~nx0.run"

  在C:\Users\Think\AppData\Local\Temp目錄下生成了test.bat.run文件,文件的內容果真爲Y。至於生成的文件有何意義,之後再說。到如今位置我忽然感慨,我很喜歡TOMCAT,它作了什麼我都能知道,在接下來的一段時間內,我想把我看TOMCAT源代碼的感覺也下下來。也跟你們討論一下TOMCAT的工做原理。有點遠,扯回來,下面看一下92行的內容:

if not exist "%TEMP%\%~nx0.run" goto mainEntry

  這個一眼就看明白了,再次判斷%~nx0.run文件是否存在,若是仍是不存在,那麼直接到mainEntry節點,因爲咱們此時此文件已經建立成功,那麼順序執行到第93行。

  93行的內容爲:  

echo Y>"%TEMP%\%~nx0.Y"

  這個同91行命令,再也不強調。順序執行到92行。

  92行的內容爲:  

  call "%~f0" %* <"%TEMP%\%~nx0.Y"

  看到以後感受依然是蒙圈,這裏面有兩個點須要你們掌握:%~f0, %* 知道這兩組符號是什麼意思,就解決了。

  %~f0:表示運行的文件的全路徑,假如我在test.bat中如此寫:  

@echo off 
@echo %%~f0 is %~f0

  那麼執行結果爲:

  

     OK。

  %*:在batch file中,每個命令的參數都以%1,%2,%3 .....的形式展示,咱們也可使用%來代替全部的參數,下面看修改萬能測試文件test.bat中的內容以下:  

@echo off 
echo First argument: [%1]
echo Second argument: [%2]
echo Third argument: [%3]
echo Fourth argument: [%4]
echo Fifth  argument: [%4]
echo Entire command line: [%*]

  查看運行結果:

  

  意思就是將在catalina.bat文件中本身調用本身,傳遞參數Y,下面看一下測試,將test.bat中的內容改成:  

@echo off 
call "%~f0" %* <"%TEMP%\%~nx0.Y"

  查看運行結果,在程序運行了一段時間之後,得出以下結論:

  

  很奇怪,奇怪亮點,爲何運行的時候會有停頓,第二,爲何會產生這個結果。下面解決這兩個困惑,我以爲程序在運行的時候確定是在後臺運行什麼操做了,因此我將test.bat中的內容改了一下:     

call "%~f0" %* <"%TEMP%\%~nx0.Y"

  而後再次運行,獲得結果:

  

  原來程序在輸出最終結果以前一直到在調用本身,因此會有一個停頓的感受。

  第二:爲何會產生這個結果:

    

  下面看第96行的內容:  

  set RETVAL=%ERRORLEVEL%

  在前面的的內容中可能給你們一種誤解,因此在看到這句話的時候,不知道是否是也有人跟我似的直接去環境變量中找ERRORLEVEL的值,找不到以後以爲我在忽悠你們,下面我跟你們說說這個ERRORLEVEL。不知道你們是否是瞭解在Linux中的$?這個結果返回值,其實ERRORLEVEL和$?差很少,都是用來表示上次執行結果的,若是返回0說明執行正確,若是不是0說明執行失敗。例如在test.bat中的內容:  

call %ERRORLEVEL%

  執行結果:

  

  下面看97行的內容:  

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

  這裏面有/Q, >NUL, 2>&1須要跟你們解釋一下:

  /Q: 跟在del後面表示不須要交互式的刪除。安靜模式的意思。如在test.bat中的內容以下:  

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

  而後運行結果爲:

  

  此時文件系統中的文件確實已經被刪除,只是在刪除的過程當中沒有顯示刪除的過程,下面咱們從新建立此文件,而後把/Q標記去掉之後在嘗試一次:

  >NUL 就是將輸出輸出到NUL中,這樣有錯誤的狀況下你什麼都拿不到。

  2>&1:2是值錯誤輸出,&1是標準輸出,意思就是將錯誤輸出重定向到標準輸出中

   >NUL 2>&1的意思就是將錯誤輸出重定向到標準輸出,最後在重定向到NUL中,這樣出現錯誤,你從表面上不會看出來。若是將test.bat中的刪除操做執行屢次,  

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

  看結果:

  

  也不會顯示異常,若是將>NUL 2>&1刪除之後,再次執行:

@echo off
del /Q "%TEMP%\%~nx0.Y"

  結果就會顯示出異常:

  

  下面看第98行的內容:  

exit /B %RETVAL%

   下面的mainEntry和gotHome節點的信息同前一節剛開始的內容同樣,全部就再也不說明,若是對此有什麼疑問,請查看查看tomcat啓動文件都乾點啥一節。在接下來的部分中我想把115-137行的內容放在一塊兒說明,由於他們分爲兩部分,分別引入setenv.bat和setclasspath.bat並執行,

: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 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

  這部分的操做就是設置環境變量,因爲在tomcat7.0.8版本中不存在setenv.bat因此就不說了,setclasspath.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 Set JAVA_HOME or JRE_HOME if not already set, ensure any provided settings
rem are valid and consistent with the selected start-up options and set up the
rem endorsed directory. 
rem
rem $Id: setclasspath.bat 964208 2010-07-14 21:24:45Z markt $
rem ---------------------------------------------------------------------------

rem Make sure prerequisite environment variables are set
if not "%JAVA_HOME%" == "" goto gotJdkHome
if not "%JRE_HOME%" == "" goto gotJreHome
echo Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
echo At least one of these environment variable is needed to run this program
goto exit

:gotJreHome
if not exist "%JRE_HOME%\bin\java.exe" goto noJavaHome
if not exist "%JRE_HOME%\bin\javaw.exe" goto noJavaHome
if not ""%1"" == ""debug"" goto okJavaHome
echo JAVA_HOME should point to a JDK in order to run in debug mode.
goto exit

:gotJdkHome
if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
if not exist "%JAVA_HOME%\bin\javaw.exe" goto noJavaHome
if not exist "%JAVA_HOME%\bin\jdb.exe" goto noJavaHome
if not exist "%JAVA_HOME%\bin\javac.exe" goto noJavaHome
if not "%JRE_HOME%" == "" goto okJavaHome
set "JRE_HOME=%JAVA_HOME%"
goto okJavaHome

:noJavaHome
echo The JAVA_HOME environment variable is not defined correctly
echo This environment variable is needed to run this program
echo NB: JAVA_HOME should point to a JDK not a JRE
goto exit
:okJavaHome

if not "%BASEDIR%" == "" goto gotBasedir
echo The BASEDIR environment variable is not defined
echo This environment variable is needed to run this program
goto exit
:gotBasedir
if exist "%BASEDIR%\bin\setclasspath.bat" goto okBasedir
echo The BASEDIR environment variable is not defined correctly
echo This environment variable is needed to run this program
goto exit
:okBasedir

rem Don't override the endorsed dir if the user has set it previously
if not "%JAVA_ENDORSED_DIRS%" == "" goto gotEndorseddir
rem Set the default -Djava.endorsed.dirs argument
set "JAVA_ENDORSED_DIRS=%BASEDIR%\endorsed"
:gotEndorseddir

rem Set standard command for invoking Java.
rem Note that NT requires a window name argument when using start.
rem Also note the quoting as JAVA_HOME may contain spaces.
set _RUNJAVA="%JRE_HOME%\bin\java"
set _RUNJDB="%JAVA_HOME%\bin\jdb"

goto end

:exit
exit /b 1

:end
exit /b 0
View Code

  其中就是關於JAVA環境的一些校驗和變量的設置,重要性不言而喻,因此若是執行本步操做失敗的狀況下,程序將退出執行。

  接下來是設置CLASSPATH的內容,看過前面的說明之後,對於下面的內容應該很容易就能看懂:  

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

  將tomcat-juli.jar和bootstrap.jar的全路徑追加到CLASSPATH中,究竟這兩個jar包是作什麼的,不是本文的範疇,只說明這兩個jar包須要在CLASSPATH中體現。

  接下來是關於Log選項的問題:  

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%
View Code

  內容很簡單,一看就明白,因此也很少說了。

  在前面準備了這麼久,接下來終於到執行的時候了。下面看一下這段腳本:  

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

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

: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 Execute Java with the applicable properties
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
View Code

  前三行的內容是將當前設置的變量進行輸出,

echo Using CATALINA_BASE:   "%CATALINA_BASE%"
echo Using CATALINA_HOME:   "%CATALINA_HOME%"
echo Using CATALINA_TMPDIR: "%CATALINA_TMPDIR%"

  CATALINA_BASE,CATALINA_HOME,CATALINA_TMPDIR這三個變量在startup.bat或者catalina.bat中已經提早設置了,射出只是爲了提示用戶當前的運行環境,接下來看181-187行的內容:  

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%"

  在解釋這段內容以前,我建議你們要對setclasspath.bat中的內容有所瞭解,由於setclasspath.bat中包含對與JRE_HOME,JAVA_HOME變量的邏輯處理和定義。這段內容的意思就是說若是catalina.bat接收到的第一個參數是debug,那麼就到use_jdk節點,因爲通常狀況下咱們是用startup.bat腳本調用catalina.bat腳本,因此第一個參數應該是start,因此應該順序執行到182行echo Using JRE_HOME: "%JRE_HOME%",而後執行到java_dir_displayed節點,至於爲何debug的時候不使用JRE_HOME這個變量,咱們先記下,在之後的章節中在討論。

  在189-194行中是設置一些變量,內容以下:

set _EXECJAVA=%_RUNJAVA%
set MAINCLASS=org.apache.catalina.startup.Bootstrap
set ACTION=start
set SECURITY_POLICY_FILE=
set DEBUG_OPTS=
set JPDA=

  這裏面要說兩點,%_RUNJAVA%變量和org.apache.catalina.startup.Bootstrap,其中%_RUNJAVA%是在setclasspath.bat文件中定義的,其值爲"%JRE_HOME%\bin\java",

MAINCLASS寫過JAVA程序的人應該都知道是作什麼用的,關鍵是org.apache.catalina.startup.Bootstrap這個值是怎麼來的,在哪裏定義的,記得在catalina.bat中有過這麼一個設置:CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar,其中org.apache.catalina.startup.Bootstrap就是該jar包中的一個類。具體內容以及意義再也不此展開。
  第196行-211行是對jpda()的處理,由於我們沒有涉及,關於jdpa的內容不在此展開,由於咱們不涉及因此跳過此步驟:  
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

  再次記下一個知識點JDPA。

  下面到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

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

  其中

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

  是根據用戶輸入的具體命令,跳轉到具體的處理節點,例如輸入的命令,那麼就到doStart節點,219行-230行的內容是,若是你輸入的第一個參數再也不預設的命令當中,給你的提示: 

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

  下面先看232行-240行的doDebug節點的內容:  

: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

  一樣%_RUNJDB%變量去setclasspath.bat文件中找定義,235行的內容配置DEBUG_OPTS,接下來是安全策略的問題,若是指定參數"-security",那麼就須要加載安全策略文件,安全策略文件爲%CATALINA_BASE%\conf\catalina.policy,內容以下:  

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

// ============================================================================
// catalina.policy - Security Policy Permissions for Tomcat 7
//
// This file contains a default set of security policies to be enforced (by the
// JVM) when Catalina is executed with the "-security" option.  In addition
// to the permissions granted here, the following additional permissions are
// granted specific to each web application:
//
// * Read access to its document root directory
// * Read, write and delete access to its working directory
//
// $Id: catalina.policy 981453 2010-08-02 11:00:51Z markt $
// ============================================================================


// ========== SYSTEM CODE PERMISSIONS =========================================


// These permissions apply to javac
grant codeBase "file:${java.home}/lib/-" {
        permission java.security.AllPermission;
};

// These permissions apply to all shared system extensions
grant codeBase "file:${java.home}/jre/lib/ext/-" {
        permission java.security.AllPermission;
};

// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jre
grant codeBase "file:${java.home}/../lib/-" {
        permission java.security.AllPermission;
};

// These permissions apply to all shared system extensions when
// ${java.home} points at $JAVA_HOME/jre
grant codeBase "file:${java.home}/lib/ext/-" {
        permission java.security.AllPermission;
};


// ========== CATALINA CODE PERMISSIONS =======================================


// These permissions apply to the daemon code
grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {
        permission java.security.AllPermission;
};

// These permissions apply to the logging API
// Note: If tomcat-juli.jar is in ${catalina.base} and not in ${catalina.home},
// update this section accordingly.
//  grant codeBase "file:${catalina.base}/bin/tomcat-juli.jar" {..}
grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
        permission java.io.FilePermission
         "${java.home}${file.separator}lib${file.separator}logging.properties", "read"; 

        permission java.io.FilePermission
         "${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
        permission java.io.FilePermission
         "${catalina.base}${file.separator}logs", "read, write";
        permission java.io.FilePermission
         "${catalina.base}${file.separator}logs${file.separator}*", "read, write";

        permission java.lang.RuntimePermission "shutdownHooks";
        permission java.lang.RuntimePermission "getClassLoader";
        permission java.lang.RuntimePermission "setContextClassLoader";

        permission java.util.logging.LoggingPermission "control";

        permission java.util.PropertyPermission "java.util.logging.config.class", "read";
        permission java.util.PropertyPermission "java.util.logging.config.file", "read";
        permission java.util.PropertyPermission "catalina.base", "read";

        // Note: To enable per context logging configuration, permit read access to
        // the appropriate file. Be sure that the logging configuration is
        // secure before enabling such access.
        // E.g. for the examples web application:
        // permission java.io.FilePermission "${catalina.base}${file.separator}
        //  webapps${file.separator}examples${file.separator}WEB-INF
        //  ${file.separator}classes${file.separator}logging.properties", "read";
};

// These permissions apply to the server startup code
grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
        permission java.security.AllPermission;
};

// These permissions apply to the servlet API classes
// and those that are shared across all class loaders
// located in the "lib" directory
grant codeBase "file:${catalina.home}/lib/-" {
        permission java.security.AllPermission;
};


// If using a per instance lib directory, i.e. ${catalina.base}/lib,
// then the following permission will need to be uncommented
// grant codeBase "file:${catalina.base}/lib/-" {
//         permission java.security.AllPermission;
// };


// ========== WEB APPLICATION PERMISSIONS =====================================


// These permissions are granted by default to all web applications
// In addition, a web application will be given a read FilePermission
// and JndiPermission for all files and directories in its document root.
grant {
    // Required for JNDI lookup of named JDBC DataSource's and
    // javamail named MimePart DataSource used to send mail
    permission java.util.PropertyPermission "java.home", "read";
    permission java.util.PropertyPermission "java.naming.*", "read";
    permission java.util.PropertyPermission "javax.sql.*", "read";

    // OS Specific properties to allow read access
    permission java.util.PropertyPermission "os.name", "read";
    permission java.util.PropertyPermission "os.version", "read";
    permission java.util.PropertyPermission "os.arch", "read";
    permission java.util.PropertyPermission "file.separator", "read";
    permission java.util.PropertyPermission "path.separator", "read";
    permission java.util.PropertyPermission "line.separator", "read";

    // JVM properties to allow read access
    permission java.util.PropertyPermission "java.version", "read";
    permission java.util.PropertyPermission "java.vendor", "read";
    permission java.util.PropertyPermission "java.vendor.url", "read";
    permission java.util.PropertyPermission "java.class.version", "read";
    permission java.util.PropertyPermission "java.specification.version", "read";
    permission java.util.PropertyPermission "java.specification.vendor", "read";
    permission java.util.PropertyPermission "java.specification.name", "read";

    permission java.util.PropertyPermission "java.vm.specification.version", "read";
    permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
    permission java.util.PropertyPermission "java.vm.specification.name", "read";
    permission java.util.PropertyPermission "java.vm.version", "read";
    permission java.util.PropertyPermission "java.vm.vendor", "read";
    permission java.util.PropertyPermission "java.vm.name", "read";

    // Required for OpenJMX
    permission java.lang.RuntimePermission "getAttribute";

    // Allow read of JAXP compliant XML parser debug
    permission java.util.PropertyPermission "jaxp.debug", "read";

    // All JSPs need to be able to read this package
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat";

    // Precompiled JSPs need access to these packages.
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.el";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";
    permission java.lang.RuntimePermission
     "accessClassInPackage.org.apache.jasper.runtime.*";

    // Precompiled JSPs need access to these system properties.
    permission java.util.PropertyPermission
     "org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "read";
    permission java.util.PropertyPermission
     "org.apache.el.parser.COERCE_TO_ZERO", "read";

    // The cookie code needs these.
    permission java.util.PropertyPermission
     "org.apache.catalina.STRICT_SERVLET_COMPLIANCE", "read";
    permission java.util.PropertyPermission
     "org.apache.tomcat.util.http.ServerCookie.STRICT_NAMING", "read";
    permission java.util.PropertyPermission
     "org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR", "read";

    // Applications using Comet need to be able to access this package
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.comet";
};


// The Manager application needs access to the following packages to support the
// session display functionality
grant codeBase "file:${catalina.base}/webapps/manager/-" {
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
};

// You can assign additional permissions to particular web applications by
// adding additional "grant" entries here, based on the code base for that
// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
//
// Different permissions can be granted to JSP pages, classes loaded from
// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
//
// For instance, assume that the standard "examples" application
// included a JDBC driver that needed to establish a network connection to the
// corresponding database and used the scrape taglib to get the weather from
// the NOAA web server.  You might create a "grant" entries like this:
//
// The permissions granted to the context root directory apply to JSP pages.
// grant codeBase "file:${catalina.base}/webapps/examples/-" {
//      permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
//      permission java.net.SocketPermission "*.noaa.gov:80", "connect";
// };
//
// The permissions granted to the context WEB-INF/classes directory
// grant codeBase "file:${catalina.base}/webapps/examples/WEB-INF/classes/-" {
// };
//
// The permission granted to your JDBC driver
// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
//      permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
// };
// The permission granted to the scrape taglib
// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
//      permission java.net.SocketPermission "*.noaa.gov:80", "connect";
// };
View Code

  裏面涉及到一些權限的設置,有興趣你們能夠仔細研究。最終執行execCmd節點的腳本。

  242行-248行doRun節點內容以下:  

:doRun
shift
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set "SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy"
goto execCmd

  內容同doDebug內容類似,只是判斷是否是須要加載安全配置文件。

  250行-263行的doStart節點:  

: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

  主要內容就是,若是%OS%環境變量不是Windows_NT,那麼不設置標題,直接判斷是否須要加載安全配置文件,若是%OS%環境變量的值爲Windows_NT,那麼設置Title變量,若是沒有指定Title變量,默認值爲Tomcat,設置完_EXECJAVA變量之後,執行execCmd節點的腳本。

  265行-269行的doStop節點,內容比較簡單,主要就是設置一下ACTION變量,內容以下:  

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

  271行-273行的doVersion節點,就是調用了一下"%CATALINA_HOME%\lib\catalina.jar"中的org.apache.catalina.util.ServerInfo方法,內容以下:  

:doVersion
%_EXECJAVA% -classpath "%CATALINA_HOME%\lib\catalina.jar" org.apache.catalina.util.ServerInfo
goto end

  下面真正的重點來了,execCmd節點,其中有和startup.bat中處理參與同樣功能的節點setArgs,從279行-283行,循環讀出參數中的內容追加到CMD_LINE_ARGS變量中,內容以下:  

set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs

  286行-300行的內容就是真正的執行方法了,先看內容:  

rem Execute Java with the applicable properties
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

  是否是有點長,是否是有點看不懂,是否是以爲很麻煩,不要着急,我想一個辦法,更直觀的觀察這裏面到底是什麼東西:下面我在這些腳本上添點東西,弄成這個樣子: 

rem Execute Java with the applicable properties
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%
echo 1 %_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%
echo 2 %_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%
echo 3 %_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%
echo 4 %_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
pause

  其實很簡單,就是把內容輸出,而後爲了能看清,我在後面加了個pause,嘿嘿,下面我從startup.bat啓動catalina.bat之後看輸出結果:

Using CATALINA_BASE:   "F:\apache-tomcat-7.0.8"
Using CATALINA_HOME:   "F:\apache-tomcat-7.0.8"
Using CATALINA_TMPDIR: "F:\apache-tomcat-7.0.8\temp"
Using JRE_HOME:        "E:\Program Files\Java\jdk1.7.0_40"
Using CLASSPATH:       "F:\apache-tomcat-7.0.8\bin\bootstrap.jar;F:\apache-tomca
t-7.0.8\bin\tomcat-juli.jar"
1 start "Tomcat" "E:\Program Files\Java\jdk1.7.0_40\bin\java"  -Djava.util.loggi
ng.config.file="F:\apache-tomcat-7.0.8\conf\logging.properties" -Djava.util.logg
ing.manager=org.apache.juli.ClassLoaderLogManager   -Djava.endorsed.dirs="F:\apa
che-tomcat-7.0.8\endorsed" -classpath "F:\apache-tomcat-7.0.8\bin\bootstrap.jar;
F:\apache-tomcat-7.0.8\bin\tomcat-juli.jar" -Dcatalina.base="F:\apache-tomcat-7.
0.8" -Dcatalina.home="F:\apache-tomcat-7.0.8" -Djava.io.tmpdir="F:\apache-tomcat
-7.0.8\temp" org.apache.catalina.startup.Bootstrap  start
請按任意鍵繼續. . .

  分析一下結果得出以下結論:  

_EXECJAVA=start "Tomcat" "E:\Program Files\Java\jdk1.7.0_40\bin\java" 
JAVA_OPTS= -Djava.util.logging.config.file="F:\apache-tomcat-7.0.8\conf\logging.properties" 
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 
CATALINA_OPTS= 
DEBUG_OPTS= 
-Djava.endorsed.dirs="F:\apache-tomcat-7.0.8\endorsed" 
-classpath "F:\apache-tomcat-7.0.8\bin\bootstrap.jar;F:\apache-tomcat-7.0.8\bin\tomcat-juli.jar" 
-Dcatalina.base="F:\apache-tomcat-7.0.8" 
-Dcatalina.home="F:\apache-tomcat-7.0.8" 
-Djava.io.tmpdir="F:\apache-tomcat-7.0.8\temp" 
MAINCLASS=org.apache.catalina.startup.Bootstrap 
CMD_LINE_ARGS= ACTION=start

  至於其餘狀況,你們本身研究吧,但願能起到拋磚引玉的做用。在文中有三處疑問(標紅加粗字體),因爲和本文關心不太大,在之後說明,若是誰願意交流也能夠寫在評論中,昨天晚上寫了這些,腦殼都混亂了,好像若是有不正確的地方,歡迎你們指認。

相關文章
相關標籤/搜索