tomcat研究
来源:互联网 发布:to:day软件 编辑:程序博客网 时间:2024/05/21 06:50
tomcat启动(一)
tomcat启动命令
安装tomcat之后,设置CATALINA_HOME=tomcat的安装目录,比如安装在c:/tomcat,那么CATALINA_HOME=c:/tomcat,添加路径到path环境变量,%CATALINA_HOME%/bin,然后打开控制台,进入tomcat的bin目录,这儿有tomcat的启动脚本,startup.bat启动tomcat,shutdown.bat关闭tomcat。我是在windows下做的调试,如果在linux/unix下,相应的启动脚本为startup.sh和shutdown.sh。
tomcat启动脚本解说
用文本编辑器打开startup.bat,你会看到如下,内容:
- @echo off
- if "%OS%" == "Windows_NT" setlocal
- rem ---------------------------------------------------------------------------
- rem Start script for the CATALINA Server
- rem
- rem $Id: startup.bat,v 1.6 2004/05/27 18:25:11 yoavs Exp $
- rem ---------------------------------------------------------------------------
- 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
- set EXECUTABLE=%CATALINA_HOME%/bin/catalina.bat
- rem Check that target executable exists
- 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
- set CMD_LINE_ARGS=
- :setArgs
- if ""%1""=="""" goto doneSetArgs
- set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
- shift
- goto setArgs
- :doneSetArgs
- call "%EXECUTABLE%" start %CMD_LINE_ARGS%
- :end
第一段,内容如下,先设置好变量CATALINA_HOME,然后判断是否存在脚本文件"%CATALINA_HOME%/bin/catalina.bat",如果找不到该文件,那么退出脚本的执行,提示设置CATALINA_HOME环境变量,这就是我们在安装tomcat后,要设置环境变量CATALINA_HOME的原因。
- @echo off
- if "%OS%" == "Windows_NT" setlocal
- rem ---------------------------------------------------------------------------
- rem Start script for the CATALINA Server
- rem
- rem $Id: startup.bat,v 1.6 2004/05/27 18:25:11 yoavs Exp $
- rem ---------------------------------------------------------------------------
- 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
- set EXECUTABLE=%CATALINA_HOME%/bin/catalina.bat
第二段,内容如下,用EXECUTABLE脚本指向的脚本文件,执行启动命令,传入参数start,既进入启动脚本catalina.bat的执行。
- rem Check that target executable exists
- 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
- set CMD_LINE_ARGS=
- :setArgs
- if ""%1""=="""" goto doneSetArgs
- set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
- shift
- goto setArgs
- :doneSetArgs
- call "%EXECUTABLE%" start %CMD_LINE_ARGS%
- :end
catalina.bat内容如下:
- @echo off
- 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 "stop", 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
- rem JAVA_OPTS (Optional) Java runtime options used when the "start",
- rem "stop", or "run" command is executed.
- rem
- rem JSSE_HOME (Optional) May point at your Java Secure Sockets Extension
- rem (JSSE) installation, whose JAR files will be added to the
- rem system class path used to start Tomcat.
- rem
- rem JPDA_TRANSPORT (Optional) JPDA transport used when the "jpda start"
- rem command is executed. The default is "dt_shmem".
- rem
- rem JPDA_ADDRESS (Optional) Java runtime options used when the "jpda start"
- rem command is executed. The default is "jdbconn".
- rem
- rem $Id: catalina.bat,v 1.9.2.2 2004/09/23 20:17:14 yoavs Exp $
- rem ---------------------------------------------------------------------------
- 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 Get standard environment variables
- if exist "%CATALINA_HOME%/bin/setenv.bat" call "%CATALINA_HOME%/bin/setenv.bat"
- 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"
- rem Add on extra jar files to CLASSPATH
- if "%JSSE_HOME%" == "" goto noJsse
- set CLASSPATH=%CLASSPATH%;%JSSE_HOME%/lib/jcert.jar;%JSSE_HOME%/lib/jnet.jar;%JSSE_HOME%/lib/jsse.jar
- :noJsse
- 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 ----- Execute The Requested Command ---------------------------------------
- echo Using CATALINA_BASE: %CATALINA_BASE%
- echo Using CATALINA_HOME: %CATALINA_HOME%
- echo Using CATALINA_TMPDIR: %CATALINA_TMPDIR%
- echo Using JAVA_HOME: %JAVA_HOME%
- 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_shmem
- :gotJpdaTransport
- if not "%JPDA_ADDRESS%" == "" goto gotJpdaAddress
- set JPDA_ADDRESS=jdbconn
- :gotJpdaAddress
- 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%/../../jakarta-tomcat-catalina/catalina/src/share"
- 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
- set _EXECJAVA=start "Tomcat" %_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
- goto execCmd
- :doVersion
- %_EXECJAVA% -classpath "%CATALINA_HOME%/server/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% -Xdebug -Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=n %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% -Xdebug -Xrunjdwp:transport=%JPDA_TRANSPORT%,address=%JPDA_ADDRESS%,server=y,suspend=n %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
解释,1。再次验证catalina.bat;2。调用setclasspath.bat设置java虚拟机相关的环境变量,所以在运行tomcat的前,一定要先安装jdk,并设置好JAVA_HOME环境变量;3。设置启动程序,添加CLASSPATH,bootstrap.jar,和启动类org.apache.catalina.startup.Bootstrap;4。最后执行虚拟机,运行tomcat。运行tomcat的参数行为%_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%,在我的电脑上调试,将所有的变量内容转译出来,执行的命令即为:start "Tomcat" "C:/j2sdk1.4.2_15/bin/java" -Djava.endorsed.dirs="C:/Tomcat 5.0/common/endorsed" -classpath "C:/j2sdk1.4.2_15/lib/tools.jar;C:/Tomcat 5.0/bin/bootstrap.jar" -Dcatalina.base="C:/Tomcat 5.0" -Dcatalina.home="C:/Tomcat 5.0" -Djava.io.tmpdir="C:/Tomcat 5.0/temp" org.apache.catalina.startup.Bootstrap start
在该命令中,start "Tomcat"是在控制态打开一个新的窗口,然后运行java虚拟机C:/j2sdk1.4.2_15/bin/java,现在大家应该明白了,tomcat是从bootstrap.jar中的org.apache.catalina.startup.Bootstrap类的main函数开始启动运行,并且传入了start参数。-D开始的都是虚拟机的运行参数。
用winrar打开bootstrap.jar打开,在META-INF目录下打开MANIFEST.MF,你会看到如下内容: Manifest-Version: 1.0 Ant-Version: Apache Ant 1.6.1 Created-By: 1.4.2-b28 (Sun Microsystems Inc.) Main-Class: org.apache.catalina.startup.Bootstrap Specification-Title: Catalina Specification-Version: 1.0 Class-Path: jmx.jar commons-daemon.jar commons-logging-api.jar 指定了该jar包从那个类开始运行,依赖那些jar包。
结论
通过对脚本的研究,我们应该知道,tomcat从那儿开始运行,只有有了运行的线索,那么我们就可以从头开始调试tomcat源代码。调试tomcat源代码的准备工作,从www.apache.org上下载相应版本,带源代码的安装程序,并安装。
建立tomcat调试环境(二)
1。准备工作
下载tomcat,我下载的是tomcat5.0.30,我认为这是一个比较好的版本。下载地址http://archive.apache.org/dist/tomcat/tomcat-5/v5.0.30/bin/,选择window下载安装文件。
安装的时候,选择安装源代码选项,如下图。我的tomcat安装目录是C:/Tomcat 5.0
安装myeclipse,我安装的是5.5版。
2。创建工程
tomcat的整个安装目录拷贝到myeclipse的workspace目录下,如下图:
然后创建一个名为Tomcat 5.0的java project,如下步骤。
第一步,选择创建project,如下图:
第二步,选择java project:
第三步,选择和tomcat拷贝目录同名的project,如下图,选择“Finish”按钮。
这时候,你已经创建了tomcat的调试环境。
你可能会看到一些红色编译错误,你还需要下载mail.jar,activation.jar两个库文件,添加到工程中。
工程中估计还有一些编译错误,大家可以自己修改代码来解决,应该很简单。
3。开始调试
打开文件Bootstrap.java,所在的包为package org.apache.catalina.startup,如下图:
这就是tomcat的启动文件(大家可以通过文件搜索来找到该文件所在路径),找到main方法,tomcat就从这个main方法的地方开始运行启动,你现在可以设置断点,开始运行。
由于时间的原因,我都写的比较检阅,如果对myeclipse和tomcat有一定了解的朋友,肯定能很快建立环境。
tomcat启动main函数(三)
有了上面的准备工作,我们开始源代码调试。
main函数说明
开打Bootstrap.java,找到main函数,函数源代码如下:
- public static void main(String args[]) {
- try {
- // Attempt to load JMX class
- new ObjectName("test:foo=bar");
- } catch (Throwable t) {
- System.out.println(JMX_ERROR_MESSAGE);
- try {
- // Give users some time to read the message before exiting
- Thread.sleep(5000);
- } catch (Exception ex) {
- }
- return;
- }
- if (daemon == null) {
- daemon = new Bootstrap();
- try {
- daemon.init();
- } catch (Throwable t) {
- t.printStackTrace();
- return;
- }
- }
- try {
- String command = "start";
- if (args.length > 0) {
- command = args[args.length - 1];
- }
- if (command.equals("startd")) {
- args[0] = "start";
- daemon.load(args);
- daemon.start();
- } else if (command.equals("stopd")) {
- args[0] = "stop";
- daemon.stop();
- } else if (command.equals("start")) {
- daemon.setAwait(true);
- daemon.load(args);
- daemon.start();
- } else if (command.equals("stop")) {
- daemon.stopServer(args);
- }
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
上面的代码一共分成三部分: 第一部分:
- try {
- // Attempt to load JMX class
- new ObjectName("test:foo=bar");
- } catch (Throwable t) {
- System.out.println(JMX_ERROR_MESSAGE);
- try {
- // Give users some time to read the message before exiting
- Thread.sleep(5000);
- } catch (Exception ex) {
- }
- return;
- }
验证jdk基础类是否载入,没有载入,在标准输入打印错误信息,然后退出程序运行。
第二部分:
- if (daemon == null) {
- daemon = new Bootstrap();
- try {
- daemon.init();
- } catch (Throwable t) {
- t.printStackTrace();
- return;
- }
- }
初始化运行环境,载入需要的jar包,读取conf/server.xml,生成相应的运行对象:
第三部分:
- try {
- String command = "start";
- if (args.length > 0) {
- command = args[args.length - 1];
- }
- if (command.equals("startd")) {
- args[0] = "start";
- daemon.load(args);
- daemon.start();
- } else if (command.equals("stopd")) {
- args[0] = "stop";
- daemon.stop();
- } else if (command.equals("start")) {
- daemon.setAwait(true);
- daemon.load(args);
- daemon.start();
- } else if (command.equals("stop")) {
- daemon.stopServer(args);
- }
- } catch (Throwable t) {
- t.printStackTrace();
- }
装载,开始运行。
jar运行库载入(四)
前面讲述了main函数三段的主要任务,第一段基本库验证没什么好说的了。下面我们开始第二段的调试。
- if (daemon == null) {
- daemon = new Bootstrap();
- try {
- daemon.init();
- } catch (Throwable t) {
- t.printStackTrace();
- return;
- }
- }
从上面我们可以看得出,首先,创建了一个Bootstrap对象,然后进入该对象的额init方法,进行初始化处理。下面我们看看init方法的内容:
- public void init() throws Exception
- {
- // Set Catalina path
- setCatalinaHome();
- setCatalinaBase();
- initClassLoaders();
- Thread.currentThread().setContextClassLoader(catalinaLoader);
- SecurityClassLoad.securityClassLoad(catalinaLoader);
- // Load our startup class and call its process() method
- if (debug >= 1)
- log("Loading startup class");
- Class startupClass =
- catalinaLoader.loadClass
- ("org.apache.catalina.startup.Catalina");
- Object startupInstance = startupClass.newInstance();
- // Set the shared extensions class loader
- if (debug >= 1)
- log("Setting startup class properties");
- String methodName = "setParentClassLoader";
- Class paramTypes[] = new Class[1];
- paramTypes[0] = Class.forName("java.lang.ClassLoader");
- Object paramValues[] = new Object[1];
- paramValues[0] = sharedLoader;
- Method method =
- startupInstance.getClass().getMethod(methodName, paramTypes);
- method.invoke(startupInstance, paramValues);
- catalinaDaemon = startupInstance;
- }
setCatalinaHome()设置catalina.home的环境变量;setCatalinaBase()设置catalina.base的环境变量,一般是等于catalina.home。initClassLoaders()载入tomcat安装目录下,子目录common/lib、server/lib、shared/lib下的jar运行时库文件,并创建对应的三个classloader:commonLoader、catalinaLoader、sharedLoader,并且commonLoader是catalinaLoader和sharedLoader的父节点。
然后创建一个org.apache.catalina.startup.Catalina类对象,调用setParentClassLoader方法,将commonLoader赋予自己的parentClassLoader成员。保存Catalina对象。这样tomcat运行的时候,需要用到的类都载入到运行环境中了。
在tomcat运行时库的载入过程中,涉及到一些关键的类,它们得关系图如下。
在方法createClassLoader中,根据传入的参数,从配置文件/org/apache/catalina/startup/catalina.properties中,根据配置参数,遍历制定的目录,得到所有的jar文件列表,将这些列表载入到制定classloader中,实现了一个classloader子类StandardClassLoader,最后用运行时库的jar作为参数,创建一个StandardClassLoader放回。
对应的时序图为
根据上面的两个图,大家对tomcat运行时库的载入,然后创建一个org.apache.catalina.startup.Catalina对象应该有了一个大体的了解,这个Catalina对象保存为Bootstrap类的成员catalinaDaemon,这个对象后面将大有用处。如果对classloader有不理解的,可以在网上搜索相关的资料,就很容易理解了。
运行时库载入就好像一个windows程序运行的时候,需要载入一些lib库那样。
载入的具体细节,大家可以浏览具体的代码。如果有感兴趣的朋友,给我留言,我们一起学习研究。
现在开始调试前提到的第三段代码
- try {
- String command = "start";
- if (args.length > 0) {
- command = args[args.length - 1];
- }
- if (command.equals("startd")) {
- args[0] = "start";
- daemon.load(args);
- daemon.start();
- } else if (command.equals("stopd")) {
- args[0] = "stop";
- daemon.stop();
- } else if (command.equals("start")) {
- daemon.setAwait(true);
- daemon.load(args);
- daemon.start();
- } else if (command.equals("stop")) {
- daemon.stopServer(args);
- }
- } catch (Throwable t) {
- t.printStackTrace();
- }
看到上面的的代码,大家应该记得我们在阅读tomcat启动脚本startup.bat的时候,传入了start参数。由于我们是调试运行,参数数组args中没有内容,第一个if之后,command =start。所以最后将运行到如下一段代码:
- } else if (command.equals("start")) {
- daemon.setAwait(true);
- daemon.load(args);
- daemon.start();
- }
设置等待参数为true;
- tomcat研究
- Tomcat研究之ClassLoader
- Tomcat研究之ClassLoader
- Tomcat ClassLoader研究
- Tomcat研究之ClassLoader
- TOMCAT内存溢出研究
- TOMCAT内存溢出研究
- Tomcat ClassLoader研究
- Tomcat源码研究
- Tomcat发布路径研究
- Tomcat研究之组件结构
- tomcat 连接池参数研究
- Tomcat研究之组件结构
- tomcat6源码研究:tomcat启动
- Tomcat解压解压版本研究
- Tomcat研究之组件结构
- Tomcat服务器层次结构研究
- Tomcat启动过程源码研究
- 第九周任务五
- mysql中如何配置命令行客户端
- java.lang.OutOfMemoryError: PermGen space及其解决方法 .
- NVDIA(英伟达)一道笔试笔试编程题
- 让windows7学会定时关机
- tomcat研究
- Windows Phone 7 学习笔记三------文本框输入作用域
- 工具App for C2DM.
- [翻译]WP7 QuickStart-第六篇-Windows Phone下文本的使用
- Android入门、源码、文档资源、教程
- 在Unity3D中应用EZGUI中的参数传递
- Scanner 和BufferedReader同样能实现将键盘输入的数据送入程序
- WP7 页面间传值
- 跑马灯