# tomcat8.5.99 **Repository Path**: mofeideyu/tomcat8.5.99 ## Basic Information - **Project Name**: tomcat8.5.99 - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-09-10 - **Last Updated**: 2024-09-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 编译 在tomcat8.5.99目录下执行指令进行编译并下载需要的jar包: ant 编译成功后出现output目录 下载的jar包在 C:\Users\Administrator\tomcat-build-libs目录下 ### 运行 将lib目录下的jar包 Add as Library 添加到library库中 运行 org.apache.catalina.startup.Bootstrap 主类启动tomcat 此时会报错误 (listener + filter) ```text org.apache.catalina.core.StandardContext listenerStart 严重: 配置应用程序监听器[listeners.ContextListener]错误 java.lang.ClassNotFoundException: listeners.ContextListener ``` 报错原因:解析webapps/examples/WEB-INF/web.xml下 没有找到对应的类 ```xml listeners.ContextListener ``` 解决方案:在webapps/examples/WEB-INF/classes目录下可以找到相关的类, 将其中的类复制到java目录下即可,并修改xml标签中的类全限定名 修复ClassNotFoundException的类都放在java>org>apache>classes目录下 ```xml org.apache.classes.listeners.ContextListener ``` 此时为了方便直接将webapps/examples/WEB-INF/classes目录直接放到java.org.apache目录下 改完之后,启动运行过程不抱任何错即可. 然后打开 http://localhost:8080,此时会报 ```text org.apache.catalina.core.StandardWrapperValve invoke 严重: 在路径为[]的上下文中,Servlet[jsp]的Servlet.service()引发了具有根本原因的异常[无法为JSP编译类] java.lang.NullPointerException: Cannot invoke "javax.servlet.jsp.JspFactory.getJspApplicationContext(javax.servlet.ServletContext)" because the return value of "javax.servlet.jsp.JspFactory.getDefaultFactory()" is null ``` 解决方案:修改org.apache.catalina.startup.ContextConfig.configureStart()方法 在webConfig();方法(大概744行)后添加 ```text //添加JSP解析器的初始化 [处理(org.apache.jasper.JasperException: 无法为JSP编译类)] context.addServletContainerInitializer(new JasperInitializer(), null); ``` 添加完之后,再次运行,访问http://localhost:8080就可以看到默认页面了 # 解析server.xml文件 ```java /** * @see org.apache.catalina.startup.Catalina#createStartDigester */ public class Catalina { protected Digester createStartDigester() { long t1 = System.currentTimeMillis(); // Initialize the digester Digester digester = new Digester(); digester.setValidating(false); digester.setRulesValidation(true); Map,List> fakeAttributes = new HashMap<>(); // Ignore className on all elements List objectAttrs = new ArrayList<>(); objectAttrs.add("className"); fakeAttributes.put(Object.class, objectAttrs); // Ignore attribute added by Eclipse for its internal tracking List contextAttrs = new ArrayList<>(); contextAttrs.add("source"); fakeAttributes.put(StandardContext.class, contextAttrs); // Ignore Connector attribute used internally but set on Server List connectorAttrs = new ArrayList<>(); connectorAttrs.add("portOffset"); fakeAttributes.put(Connector.class, connectorAttrs); digester.setFakeAttributes(fakeAttributes); digester.setUseContextClassLoader(true); // Configure the actions we will be using digester.addObjectCreate("Server", "org.apache.catalina.core.StandardServer", "className"); digester.addSetProperties("Server"); digester.addSetNext("Server", "setServer", "org.apache.catalina.Server"); digester.addObjectCreate("Server/GlobalNamingResources", "org.apache.catalina.deploy.NamingResourcesImpl"); digester.addObjectCreate("Server/Listener", null, // MUST be specified in the element "className"); digester.addObjectCreate("Server/Service", "org.apache.catalina.core.StandardService", "className"); digester.addObjectCreate("Server/Service/Listener", null, // MUST be specified in the element "className"); // Executor digester.addObjectCreate("Server/Service/Executor", "org.apache.catalina.core.StandardThreadExecutor", "className"); digester.addRule("Server/Service/Connector", new ConnectorCreateRule()); digester.addRule("Server/Service/Connector", new SetAllPropertiesRule(new String[] { "executor", "sslImplementationName" })); digester.addRule("Server/Service/Connector", new AddPortOffsetRule()); digester.addObjectCreate("Server/Service/Connector/SSLHostConfig", "org.apache.tomcat.util.net.SSLHostConfig"); digester.addRule("Server/Service/Connector/SSLHostConfig/Certificate", new CertificateCreateRule()); digester.addRule("Server/Service/Connector/SSLHostConfig/Certificate", new SetAllPropertiesRule(new String[] { "type" })); digester.addObjectCreate("Server/Service/Connector/SSLHostConfig/OpenSSLConf", "org.apache.tomcat.util.net.openssl.OpenSSLConf"); digester.addObjectCreate("Server/Service/Connector/SSLHostConfig/OpenSSLConf/OpenSSLConfCmd", "org.apache.tomcat.util.net.openssl.OpenSSLConfCmd"); digester.addObjectCreate("Server/Service/Connector/Listener", null, // MUST be specified in the element "className"); digester.addObjectCreate("Server/Service/Connector/UpgradeProtocol", null, // MUST be specified in the element "className"); // Add RuleSets for nested elements digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/")); digester.addRuleSet(new EngineRuleSet("Server/Service/")); digester.addRuleSet(new HostRuleSet("Server/Service/Engine/")); digester.addRuleSet(new ContextRuleSet("Server/Service/Engine/Host/")); addClusterRuleSet(digester, "Server/Service/Engine/Host/Cluster/"); digester.addRuleSet(new NamingRuleSet("Server/Service/Engine/Host/Context/")); // When the 'engine' is found, set the parentClassLoader. digester.addRule("Server/Service/Engine", new SetParentClassLoaderRule(parentClassLoader)); addClusterRuleSet(digester, "Server/Service/Engine/Cluster/"); long t2 = System.currentTimeMillis(); if (log.isDebugEnabled()) { log.debug("Digester for server.xml created " + (t2 - t1)); } return digester; } } ``` 其中Degister内提供三种 ```java /** * @see org.apache.tomcat.util.digester.ObjectCreateRule * @see org.apache.tomcat.util.digester.SetPropertiesRule * @see org.apache.tomcat.util.digester.SetNextRule */ // addObjectCreate 对应 addRule(pattern, new ObjectCreateRule(className, attributeName)); //digester.addObjectCreate("Server", "org.apache.catalina.core.StandardServer", "className"); // addSetProperties 对应 addRule(pattern, new SetPropertiesRule()); //digester.addSetProperties("Server"); // addSetNext 对应 addRule(pattern, new SetNextRule(methodName, paramType)); //digester.addSetNext("Server", "setServer", "org.apache.catalina.Server"); //其中 ObjectCreateRule,SetPropertiesRule,SetNextRule三类都实现了abstract class Rule抽象类 //ObjectCreateRule,SetPropertiesRule重写了begin方法;SetNextRule没有重写begin,Rule抽象父类begin什么都没做 //ObjectCreateRule内的begin方法是实例化对象 //SetPropertiesRule内的begin方法只是取出属性值,没有实际作用 ``` ### 实例化`org.apache.catalina.core.StandardServer` ```java /** * @see org.apache.catalina.core.StandardServer */ public class StandardServer extends LifecycleMBeanBase implements Server { private NamingResourcesImpl globalNamingResources = null; public StandardServer() { super(); globalNamingResources = new NamingResourcesImpl(); globalNamingResources.setContainer(this); if (isUseNaming()) { namingContextListener = new NamingContextListener(); addLifecycleListener(namingContextListener); } else { namingContextListener = null; } } } ``` ```xml ``` 对应实例化`org.apache.catalina.connector.Connector`类, ```java /** * @see org.apache.catalina.connector.Connector * @see org.apache.coyote.http11.Http11NioProtocol */ public class Connector extends LifecycleMBeanBase { //protocol="HTTP/1.1" public Connector(String protocol) { //得到 protocolHandlerClassName="org.apache.coyote.http11.Http11NioProtocol" setProtocol(protocol); // Instantiate protocol handler ProtocolHandler p = null; try { Class clazz = Class.forName(protocolHandlerClassName); p = (ProtocolHandler) clazz.getConstructor().newInstance(); } catch (Exception e) { log.error(sm.getString("coyoteConnector.protocolHandlerInstantiationFailed"), e); } finally { this.protocolHandler = p; } //...... } } ``` 将`org.apache.coyote.http11.Http11NioProtocol`实例化后并赋值给protocolHandler ```java /** * @see org.apache.coyote.http11.Http11NioProtocol */ public class Http11NioProtocol extends AbstractHttp11JsseProtocol { public Http11NioProtocol() { this(new NioEndpoint()); } } ```