# 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());
}
}
```