Tomcat源码分析-开篇(Eclipse 导入Tomcat源码项目)

Posted cao_xiaobo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat源码分析-开篇(Eclipse 导入Tomcat源码项目)相关的知识,希望对你有一定的参考价值。

 

一、安装配置Ant

 

(1)下载Ant

下载地址:https://ant.apache.org/bindownload.cgi  

下载完成后解压即用。 

 

(2)配置Ant环境变量

配置ANT_HOME=F:\\java\\apache-ant-1.10.7

path中添加:%ANT_HOME%\\bin

 

(3)查看Ant版本

命令:ant -v

到这里Ant已经安装好了。下面就准备开始导入Tomcat源码... 

 

 

二、导入Tomcat源码

 

(1)下载tomcat源码 

下载地址:https://archive.apache.org/dist/tomcat/

 

(2)修改build.properties文件

在根目录我们可以看到有一个build.properties.default文件。将其更名为build.properties,打开,找到base.path=….;并将其改为该文件的目录+/output。当然,你也可以随便写什么路径,只要你能找到就行。

 

(3)下载相关的依赖jar

打开cmd,将进入tomcat源码的根目录,输入ant 命令(这个可能会花一点时间),如图:

下载完成后目录如下:

 

(4)新建java项目

新建一个java Project,我自已把它命名为tomcat-src,然后将tomcat源码下的java和test两个文件夹以File System方式导入项目的根目录。

 

(5)导入依赖包

ant.jar:      在你安装的ant目录:ANT_HOME/lib下。
jaxrpc.jar:       在eclipse下的/plugin/ javax.xml.rpc_xxx(版本号)/lib/目录下。
org.eclipse.jdt.core_3.10.2.v20150120-1634.jar:在eclipse的plugin目录下。
wsdl-1.6.2.jar:     eclipse的plugins目录下。
hamcrest-2.1.jar    自行下载
junit-4.13.jar          自行下载
easymock-3.4:    自行下载
jar包可以直接从maven库中下载 https://mvnrepository.com/ 
导入完这些包后,可能TestCookieFilter类还会报错,这是因为CookieFilter类找不到,我们上面的输出目录output\\build\\webapps\\examples\\WEB-INF\\classes\\util中,就能找到这个类了。将其复制到TestCookieFilter的包下就OK了。

 

(6)配置启动参数

设置vm参数:-Dcatalina.home=”源码的路径\\output\\build”
在Run Configuration里面配置如下:

到此可以直接通过启动 Bootstrap 类中的main 方法启动tomcat服务了。

 

结束了 !!!


 

 

三、这个Tomcat源码项目如何启动其它web应用?(附加内容)

 

(1)在新建的java项目中创建一个conf 目录,并将源码目录下conf 的server.xml 放进去

 

(2)打开Bootstrap.java ,找到这个类的main方法,修改args参数(源码启动的时候 args参数为空值)

修改的这个args参数 在启动Bootstrap 时,会去加载这个 server.xml 文件

public static void main(String args[]) {
    // 在这时修改args参数,因为直接启动这个main方法时,args参数为空
    args = new String[]{"-config", System.getProperty("user.dir") + "\\\\conf\\\\server.xml", "start"};
    if (daemon == null) {
        // Don\'t set daemon until init() has completed
        Bootstrap bootstrap = new Bootstrap();
        try {
            bootstrap.init();
        } catch (Throwable t) {
            handleThrowable(t);
            t.printStackTrace();
            return;
        }
        daemon = bootstrap;
    } else {
        // When running as a service the call to stop will be on a new
        // thread so make sure the correct class loader is used to prevent
        // a range of class not found exceptions.
        Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
    }
    // 省略若干代码...
}

 

 

(3)修改刚才加进去的这个 server.xml 文件

代码可以从下面进行拷贝

            <Host name="localhost" appBase="webapps" unpackWARs="true"
                autoDeploy="true">

                <!-- SingleSignOn valve, share authentication between web applications 
                    Documentation at: /docs/config/valve.html -->
                <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" 
                    /> -->

                <!-- Access log processes all example. Documentation at: /docs/config/valve.html 
                    Note: The pattern used is equivalent to using pattern="common" -->
                <Valve className="org.apache.catalina.valves.AccessLogValve"
                    directory="logs" prefix="localhost_access_log" suffix=".txt"
                    pattern="%h %l %u %t &quot;%r&quot; %s %b" />
                <Context path="" reloadable="true"
                    docBase="D:\\workspace-neno\\springmvc\\src\\main\\webapp" workDir="D:\\workspace-neno\\springmvc\\work">
                    
                    <Loader className="org.apache.catalina.loader.MyDevLoader"
                        reloadable="true" debug="1" useSystemClassLoaderAsParent="false" />

                </Context>
            </Host>

 

(4)添加 org.apache.catalina.loader.MyDevLoader 这个类(就是上面截图圈起来的那个类)

在 org.apache.catalina.loader 包下新建一个类,名称为 MyDevLoader (当然可以改成你想要的名字,只要保证和server.xml 中 Loader 中的className一致就行) ;

建完类之后,直接拷贝我下面的代码:(备注:我这里用的是tomcat8,如果是tomcat7/tomcat9 的话可能要修改一些报错的内容

package org.apache.catalina.loader;  
  
import java.io.File;  
import java.io.FileFilter;  
import java.io.FileReader;  
import java.io.IOException;  
import java.io.LineNumberReader;  
import java.net.MalformedURLException;  
import java.net.URL;  
import java.util.ArrayList;  
import java.util.Iterator;  
import java.util.List;  
import java.util.StringTokenizer;  
import javax.servlet.ServletContext;  
import org.apache.catalina.LifecycleException;  
/**
 * 自定义DevLoader类
 * @author Administrator
 *
 */
public class MyDevLoader extends WebappLoader {  
    private static final String info = "org.apache.catalina.loader.DevLoader/1.0";  
    private String webClassPathFile = ".#webclasspath";  
    private String tomcatPluginFile = ".tomcatplugin";  
  
    public MyDevLoader() {  
    }  
  
    public MyDevLoader(ClassLoader parent) {  
        super(parent);  
    }  
  
    public void startInternal() throws LifecycleException {  
        log("Starting DevLoader");  
  
        super.startInternal();  
  
        ClassLoader cl = super.getClassLoader();  
        if (!(cl instanceof WebappClassLoader)) {  
            logError("Unable to install WebappClassLoader !");  
            return;  
        }  
        WebappClassLoader devCl = (WebappClassLoader) cl;  
  
        List webClassPathEntries = readWebClassPathEntries();  
        StringBuffer classpath = new StringBuffer();  
        for (Iterator it = webClassPathEntries.iterator(); it.hasNext();) {  
            String entry = (String) it.next();  
            File f = new File(entry);  
            if (f.exists()) {  
                if ((f.isDirectory()) && (!(entry.endsWith("/"))))  
                    f = new File(entry + "/");  
                try {  
                    URL url = f.toURL();  
  
                    // devCl.addRepository(url.toString());  
                    devCl.addURL(url);  
                    classpath.append(f.toString() + File.pathSeparatorChar);  
                    log("added " + url.toString());  
                } catch (MalformedURLException e) {  
                    logError(entry + " invalid (MalformedURL)");  
                }  
            } else {  
                logError(entry + " does not exist !");  
            }  
        }  
  
        String cp = (String) getServletContext().getAttribute("org.apache.catalina.jsp_classpath");  
        StringTokenizer tokenizer = new StringTokenizer(cp, File.pathSeparatorChar + "");  
        while (tokenizer.hasMoreTokens()) {  
            String token = tokenizer.nextToken();  
  
            if ((token.charAt(0) == \'/\') && (token.charAt(2) == \':\')) {  
                token = token.substring(1);  
            }  
            classpath.append(token + File.pathSeparatorChar);  
        }  
  
        getServletContext().setAttribute("org.apache.catalina.jsp_classpath", classpath.toString());  
        log("JSPCompiler Classpath = " + classpath);  
    }  
  
    protected void log(String msg) {  
        System.out.println("[DevLoader] " + msg);  
    }  
  
    protected void logError(String msg) {  
        System.err.println("[DevLoader] Error: " + msg);  
    }  
  
    protected List readWebClassPathEntries() {  
        List rc = null;  
  
        File prjDir = getProjectRootDir();  
        if (prjDir == null)  
            return new ArrayList();  
  
        log("projectdir=" + prjDir.getAbsolutePath());  
  
        rc = loadWebClassPathFile(prjDir);  
  
        if (rc == null)  
            rc = new ArrayList();  
        return rc;  
    }  
  
    protected File getProjectRootDir() {  
        File rootDir = getWebappDir();  
        FileFilter filter = new FileFilter() {  
            public boolean accept(File file) {  
                return (file.getName().equalsIgnoreCase(webClassPathFile) || file.getName().equalsIgnoreCase(tomcatPluginFile));  
            }  
        };  
        while (rootDir != null) {  
            File[] files = rootDir.listFiles(filter);  
            if ((files != null) && (files.length >= 1))  
                return files[0].getParentFile();  
  
            rootDir = rootDir.getParentFile();  
        }  
        return null;  
    }  
  
    protected List loadWebClassPathFile(File prjDir) {  
        File cpFile = new File(prjDir, this.webClassPathFile);  
        if (cpFile.exists()) {  
            FileReader reader = null;  
            try {  
                List rc = new ArrayList();  
                reader = new FileReader(cpFile);  
                LineNumberReader lr = new LineNumberReader(reader);  
                String line = null;  
                while ((line = lr.readLine()) != null) {  
                    line = line.replace(\'\\\\\', \'/\');  
                    rc.add(line);  
                }  
                return rc;  
            } catch (IOException ioEx) {  
                if (reader != null)  
                    ;  
                return null;  
            }  
        }  
        return null;  
    }  
  
    protected ServletContext getServletContext() {  
        // return ((Context) getContainer()).getServletContext();  
        return this.getContext().getServletContext();  
    }  
  
    protected File getWebappDir() {  
        File webAppDir = new File(getServletContext().getRealPath("/"));  
        return webAppDir;  
    }  
}  

 

(5)启动 BootStrap 中的main方法

这样你其它的web项目就启动了,这个就相当于eclipse插件中那个猫的图标按钮功能!

 

以上是关于Tomcat源码分析-开篇(Eclipse 导入Tomcat源码项目)的主要内容,如果未能解决你的问题,请参考以下文章

tomcat源码研究之源码导入eclipse

tomcat和mybatis源码导入eclipse

Tomcat源码导入eclipse的步骤

Tomcat8源码编译及导入Eclipse中研究

tomcat源码导入eclipse

tomcat源码学习一:导入eclipse