在本机使用maven编译tomcat8的源码并运行

前提说明:

1. 基于tomcat 8.0.26版本的源码

2. JDK1.7

操作说明:

1. 从Apache网站下载tomcat源码

2. 默认情况下,tomcat使用ant进行编译、打包,以下讲一下如何使用maven来编译、打包

3. 在Eclipse里新建一个maven标准Java项目

4. 将tomcat源码包下的Java里的文件拷贝到src/main/java下

5. 将conf和webapps拷贝到项目根路径下(请参考下图)

6. 使用以下maven配置

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.test</groupId>
	<artifactId>tomcat8</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	
	<properties>
		<maven.build.timestamp.format>yyyyMMdd HH:mm:ss</maven.build.timestamp.format>
		<VERSION>8.0.26</VERSION>
		<VERSION_NUMBER>8.0.26</VERSION_NUMBER>
		<VERSION_BUILT>${maven.build.timestamp}</VERSION_BUILT>
	</properties>
	
	<build>
		<resources>
			<resource>
				<directory>src/main/java</directory>
				<includes>
					<include>**/*.xml</include>
					<include>**/*.properties</include>
					<include>**/*.dtd</include>
					<include>**/*.xsd</include>
				</includes>
				<filtering>true</filtering>
			</resource>
			<resource>
				<directory>src/main/resources</directory>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
					<encoding>UTF-8</encoding>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-resources-plugin</artifactId>
				<configuration>
					<delimiters>
						<delimiter>@</delimiter>
					</delimiters>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.3</version>
		</dependency>
		<dependency>
			<groupId>avalon-framework</groupId>
			<artifactId>avalon-framework</artifactId>
			<version>4.1.5</version>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
		<dependency>
			<groupId>logkit</groupId>
			<artifactId>logkit</artifactId>
			<version>1.0.1</version>
		</dependency>
		<dependency>
			<groupId>servletapi</groupId>
			<artifactId>servletapi</artifactId>
			<version>2.3</version>
		</dependency>
		<dependency>
			<groupId>geronimo-spec</groupId>
			<artifactId>geronimo-spec-jaxrpc</artifactId>
			<version>1.1-rc4</version>
		</dependency>
		<dependency>
			<groupId>wsdl4j</groupId>
			<artifactId>wsdl4j</artifactId>
			<version>1.6.2</version>
		</dependency>
		<dependency>
			<groupId>org.eclipse.jdt.core.compiler</groupId>
			<artifactId>ecj</artifactId>
			<version>4.4.2</version>
		</dependency>
		<dependency>
			<groupId>commons-daemon</groupId>
			<artifactId>commons-daemon</artifactId>
			<version>1.0.15</version>
		</dependency>
		<dependency>
			<groupId>org.apache.ant</groupId>
			<artifactId>ant</artifactId>
			<version>1.9.6</version>
		</dependency>
	</dependencies>
</project>

 最终项目的文件结构如下图:

 

经过以上步骤之后,编译应该能够通过了,如果这个时候我们使用Bootstrap启动tomcat,也能正常启动,但在打开页面时,会报Validator的什么NullPointException,主要是因为JspFactory里的工厂类没有被实例化,所以getFactory总是返回null。

JspFactory的实现类是JspFactoryImpl,然后在JasperInitializer里会被调用,如果JasperInitializer能够被正常启动,那么JspFactory就不会返回Null了。

在ContextConfig的1128行,有加载所有ServletContainerInitializer的机会,这里会去加载META-INF/services下面的所有ServletContainerInitializer的实现类,所以需要在META-INF/services下新建一个文件javax.servlet.ServletContainerInitializer,然后里面的内容是org.apache.jasper.servlet.JasperInitializer,这样再启动之后,就能够正常访问页面了。

以上这点也是我比较疑惑的,我在tomcat的bin版本发行包里,没有看到哪个jar包里面有META-INF/services/javax.servlet.ServletContainerInitializer这个文件,但是tomcat却可以直接运行,但为什么使用源码编译时,就必须添加这个文件呢?以后有时间再细细研究一下。

猜你喜欢

转载自garyjiao.iteye.com/blog/2246683
今日推荐