
Tomcat源码学习(一)
|
作为一位Java程序员,如果您没有接触过开源软件、项目或框架的话,恐怕有些不可思议。轰轰烈烈的开源运动起源于Linux操作系统,Apache基金会在其中扮演了中流砥柱的角色,业界巨擘SUN,IBM, BEA 和Oracle等公司的积极参与,使得声势浩大的开源运动成为软件开发领域势不可挡的力量。2001年11月,IBM向Apache基金会捐献出Visual Age for Java,这个看似穷途末路的产品经众多高手的改造,演变为辉煌一时的Eclipse,直接击败了不开源的JBuilder,让做编译器起家的Borland公司几乎关张大吉。Eclipse这个产品如此经典,以至于微软的Visual Studio都得向它学习。在Apache Harmony的围追堵截下,Java的发明者Sun公司一看势头不妙,于2006年宣布Java开源,随后又公开了其旗舰级产品Solaris的源代码。今年1月,开源的死对头、冷酷自私的微软也不得不在MS-RL协议下公开.Net的源代码。但是,在这如火如荼的开源运动中,我们中国的程序员又有多少贡献呢,我们开创了哪些框架、项目和产品,为开源界添砖加瓦呢?以笔者短浅的目光看来,我们对开源界贡献的东西恐怕很少,能够与国外经典开源项目一较高下的,少之又少矣! |






一共有 41 条评论
Please try to access
http://localhost:8080/examples/jsp/index.html
请手动下载http://mirror.calvin.edu/eclipse/downloads/drops/R-3.2-200606291905/eclipse-JDT-3.2.zip到本地比如说D:/temp/eclipse-JDT-3.2.zip,然后修改build.properties文件中的jdt.loc= file:///D:/temp/eclipse-JDT-3.2.zip。
Tomcat 版本 6.0
Subversion 版本:CollabNetSubversion-server-1.4.6-4.win32
base.path和jdt.loc已经修改
运行ant download结果如下:
D:\svn\tomcat\src>ant download
Buildfile: build.xml
download:
setproxy:
testexist:
[echo] Testing for D:/svn/tomcat/share/tomcat-native-1.1.6/tomcat-native.t
ar.gz
downloadfile:
setproxy:
testexist:
[echo] Testing for D:/svn/tomcat/share/tomcat6-deps/dbcp/tomcat-dbcp.jar
downloadgz:
setproxy:
testexist:
[echo] Testing for D:/svn/tomcat/share/tomcat6-deps/dbcp/tomcat-dbcp.jar
downloadgz:
setproxy:
testexist:
[echo] Testing for D:/svn/tomcat/share/tomcat6-deps/dbcp/tomcat-dbcp.jar
downloadgz:
build-tomcat-dbcp:
[copy] Copying 57 files to D:\svn\tomcat\share\tomcat6-deps\dbcp
[move] Moving 57 files to D:\svn\tomcat\share\tomcat6-deps\dbcp\src\java\or
g\apache\tomcat\dbcp
[javac] Compiling 57 source files to D:\svn\tomcat\share\tomcat6-deps\dbcp\c
lasses
[javac] D:\svn\tomcat\share\tomcat6-deps\dbcp\src\java\org\apache\tomcat\dbc
p\dbcp\SQLNestedException.java:38: 警告:最后一个参数使用了不准确的变量类型的 va
rargs 方法的非 varargs 调用;
[javac] 对于 varargs 调用,应使用 java.lang.Class
[javac] 对于非 varargs 调用,应使用 java.lang.Class[],这样也可以抑制此警告
[javac] getCauseMethod = Throwable.class.getMethod("getCause", n
ull);
[javac] ^
[javac] 注意:某些输入文件使用或覆盖了已过时的 API。
[javac] 注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。
[javac] 注意:某些输入文件使用了未经检查或不安全的操作。
[javac] 注意:要了解详细信息,请使用 -Xlint:unchecked 重新编译。
[javac] 1 警告
[jar] Building jar: D:\svn\tomcat\share\tomcat6-deps\dbcp\tomcat-dbcp.jar
setproxy:
testexist:
[echo] Testing for D:/svn/tomcat/share/eclipse/plugins/org.eclipse.jdt.cor
e_3.2.0.v_671.jar
downloadzip:
[get] Getting: http://mirror.calvin.edu/eclipse/downloads/drops/R-3.2-2006
06291905/eclipse-JDT-3.2.zip
[get] To: D:\svn\tomcat\share\file.zip
[unzip] Expanding: D:\svn\tomcat\share\file.zip into D:\svn\tomcat\share
BUILD FAILED
D:\svn\tomcat\src\build.xml:554: The following error occurred while executing th
is line:
D:\svn\tomcat\src\build.xml:516: Error while expanding D:\svn\tomcat\share\file.
zip
java.util.zip.ZipException: archive is not a ZIP archive
Total time: 3 seconds
这段代码是JMX在Tomcat中的应用,请参考我的下一篇博客,JMX在Tomcat中的应用(一、二、三、四),想摘录一段如下:
4.1 上面的代码首先使用ClassLoaderFactory工厂类创建一个ClassLoader;
4.2 然后在MBeanServerFactory这个工厂类中查找MBeanServer,如果没有发现,就使用这个工厂类创建一个MBeanServer;
4.3 第三步是给刚才创建的ClassLoader这个MBean取个名字“Name: Catalina:type=ServerClassLoader,name=common”,然后注册到MBeanServer。
您如果在JConsole中观察这个MBean,会发现这个MBean没有向管理应用程序暴露任何属性和方法,并且Classloader似乎也符合JMX命名规范,它也不是一个DynamicBean,这是为什么呢?首先,这个Classloader其实一个StandardClassloader,而不是JDK中缺省的Classloader,您如果打开ClassLoaderFactory的createClassLoader方法,马上就可以看到这一点;另外,看看StanderClassloader的类签名,我们会发现该类实现了StandardClassLoaderMBean接口,这是符合JMX命名规范的;请打开StandardClassLoaderMBean接口的源代码,您会发现这是一个空接口,这意味着实现这个接口的MBean不会向管理程序暴露任何属性和方法。
private ClassLoader createClassLoader(String name, ClassLoader parent)方法时,最后的这几句不太明白:
MBeanServer mBeanServer = null;
if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
mBeanServer =
(MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);
} else {
mBeanServer = MBeanServerFactory.createMBeanServer();
}
// Register the server classloader
ObjectName objectName =
new ObjectName("Catalina:type=ServerClassLoader,name=" + name);
mBeanServer.registerMBean(classLoader, objectName);
这几句是要做什么?请指点一二.谢谢
你看看下面这篇文章对你有没有帮助?抱歉,我没有编译过Spring。
http://springide.org/project/wiki/SpringideRepository
你的网络连上了没有?如果你使用代理服务器上网,请在Build.properties文件中加上以下几行:
proxy.host=proxy.domain
proxy.port=port_number
proxy.use=on
如果还是不行,请手动从浏览器中下载下面这个文件,看看是否成功:
http://archive.apache.org/dist/tomcat/tomcat-connectors/native/tomcat-native-1.1.6-src.tar.gz
E:\data\dev\work\eclipseWork\tomcat\src>ant download
Buildfile: build.xml
download:
proxyflags:
setproxy:
testexist:
[echo] Testing for E:datadevworkeclipseWork omcatshare/tomcat-native
-1.1.14/tomcat-native.tar.gz
downloadfile:
BUILD FAILED
E:\data\dev\work\eclipseWork\tomcat\src\build.xml:664: The following error occurred while executing this line:
E:\data\dev\work\eclipseWork\tomcat\src\build.xml:657: Directory E:\data\dev\work\eclipseWork\tomcat\src\datadevworkeclipseWork omcatshare\tomcat-native-1.1.14
creation was not successful for an unknown reason
Total time: 0 seconds
E:\data\dev\work\eclipseWork\tomcat\src>
对你的问题,提供几个参考意见:
(1)最偷懒的办法是,在..\output\build\webapps\examples\WEB-INF目录下,找到web.xml文件的下面几行,把它们注释为:
<!--
<listener>
<listener-class>listeners.ContextListener</listener-class>
</listener>
<listener>
<listener-class>listeners.SessionListener</listener-class>
</listener>
-->
这样,Tomcat启动时就找不到session和context监听器,因此不需要找这两个类。
(2)如果你的Tomcat能在Eclipse中运行,请在Eclipse中找到org.apache.catalina.core.StandardContext.java文件,在其源代码的3760行(ClassLoader loader = getLoader().getClassLoader();)打个断点,然后在Eclipse调试状态下启动Tomcat,注意观察loader变量中的dirFolder或者类似的属性指向那个目录,分析以下问题所在;
(3)如果再不行,请把..\src\output\build\webapps\examples目录下所有文件打一个zip包发到我的邮箱(kww731029@gmail.com),我有时间帮你看看
我按照spring网站上的提示用svn做check out,如下:
svn co https://springframework.svn.sourceforge.net/svnroot/springframework springframework
但是并不成功,是不是这个地址有问题?
那么应该怎么办呢?我试图把下载下来的代码版spring里的src目录当做工程目录导入eclipse,但是编译时会报很多错误,应该是其中的一些jar没有导进来,于是我试图把spring目录中lib下的jar导入工程,但是我不知道如何能把这个文件夹直接导入,难道要把其中每个文件夹里的jar一个一个的放进去?
我知道肯定是我哪儿弄的不对,请楼主帮忙!谢谢!
你的错误是找不到listeners.ContextListener,这个类位于examples的webapp目录下,如果找不到,你的examples web应用将不能正常启动。请检查:
(1)在你下载的Tomcat源代码目录中,能否找到这个文件:
..\webapps\examples\WEB-INF\classes\listeners\ContextListener.java
(2)在Ant编译过的output目录中,能否找到下面这个文件:
..\output\build\webapps\examples\WEB-INF\classes\listeners\ContextListener.class
如果找不到,请把下面的源代码另存为..\webapps\examples\WEB-INF\classes\listeners\ContextListener.java,重新编译试试。
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package listeners;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* Example listener for context-related application events, which were
* introduced in the 2.3 version of the Servlet API. This listener
* merely documents the occurrence of such events in the application log
* associated with our servlet context.
*
* @author Craig R. McClanahan
* @version $Revision: 267129 $ $Date: 2004-03-18 17:40:35 +0100 (jeu., 18 mars 2004) $
*/
public final class ContextListener
implements ServletContextAttributeListener, ServletContextListener {
// ----------------------------------------------------- Instance Variables
/**
* The servlet context with which we are associated.
*/
private ServletContext context = null;
// --------------------------------------------------------- Public Methods
/**
* Record the fact that a servlet context attribute was added.
*
* @param event The servlet context attribute event
*/
public void attributeAdded(ServletContextAttributeEvent event) {
log("attributeAdded('" + event.getName() + "', '" +
event.getValue() + "')");
}
/**
* Record the fact that a servlet context attribute was removed.
*
* @param event The servlet context attribute event
*/
public void attributeRemoved(ServletContextAttributeEvent event) {
log("attributeRemoved('" + event.getName() + "', '" +
event.getValue() + "')");
}
/**
* Record the fact that a servlet context attribute was replaced.
*
* @param event The servlet context attribute event
*/
public void attributeReplaced(ServletContextAttributeEvent event) {
log("attributeReplaced('" + event.getName() + "', '" +
event.getValue() + "')");
}
/**
* Record the fact that this web application has been destroyed.
*
* @param event The servlet context event
*/
public void contextDestroyed(ServletContextEvent event) {
log("contextDestroyed()");
this.context = null;
}
/**
* Record the fact that this web application has been initialized.
*
* @param event The servlet context event
*/
public void contextInitialized(ServletContextEvent event) {
this.context = event.getServletContext();
log("contextInitialized()");
}
// -------------------------------------------------------- Private Methods
/**
* Log a message to the servlet context application log.
*
* @param message Message to be logged
*/
private void log(String message) {
if (context != null)
context.log("ContextListener: " + message);
else
System.out.println("ContextListener: " + message);
}
/**
* Log a message and associated exception to the servlet context
* application log.
*
* @param message Message to be logged
* @param throwable Exception to be logged
*/
private void log(String message, Throwable throwable) {
if (context != null)
context.log("ContextListener: " + message, throwable);
else {
System.out.println("ContextListener: " + message);
throwable.printStackTrace(System.out);
}
}
}
另外,该目录下还有一个SessionListener.java文件:
/*
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package listeners;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* Example listener for context-related application events, which were
* introduced in the 2.3 version of the Servlet API. This listener
* merely documents the occurrence of such events in the application log
* associated with our servlet context.
*
* @author Craig R. McClanahan
* @version $Revision: 267129 $ $Date: 2004-03-18 17:40:35 +0100 (jeu., 18 mars 2004) $
*/
public final class SessionListener
implements ServletContextListener,
HttpSessionAttributeListener, HttpSessionListener {
// ----------------------------------------------------- Instance Variables
/**
* The servlet context with which we are associated.
*/
private ServletContext context = null;
// --------------------------------------------------------- Public Methods
/**
* Record the fact that a servlet context attribute was added.
*
* @param event The session attribute event
*/
public void attributeAdded(HttpSessionBindingEvent event) {
log("attributeAdded('" + event.getSession().getId() + "', '" +
event.getName() + "', '" + event.getValue() + "')");
}
/**
* Record the fact that a servlet context attribute was removed.
*
* @param event The session attribute event
*/
public void attributeRemoved(HttpSessionBindingEvent event) {
log("attributeRemoved('" + event.getSession().getId() + "', '" +
event.getName() + "', '" + event.getValue() + "')");
}
/**
* Record the fact that a servlet context attribute was replaced.
*
* @param event The session attribute event
*/
public void attributeReplaced(HttpSessionBindingEvent event) {
log("attributeReplaced('" + event.getSession().getId() + "', '" +
event.getName() + "', '" + event.getValue() + "')");
}
/**
* Record the fact that this web application has been destroyed.
*
* @param event The servlet context event
*/
public void contextDestroyed(ServletContextEvent event) {
log("contextDestroyed()");
this.context = null;
}
/**
* Record the fact that this web application has been initialized.
*
* @param event The servlet context event
*/
public void contextInitialized(ServletContextEvent event) {
this.context = event.getServletContext();
log("contextInitialized()");
}
/**
* Record the fact that a session has been created.
*
* @param event The session event
*/
public void sessionCreated(HttpSessionEvent event) {
log("sessionCreated('" + event.getSession().getId() + "')");
}
/**
* Record the fact that a session has been destroyed.
*
* @param event The session event
*/
public void sessionDestroyed(HttpSessionEvent event) {
log("sessionDestroyed('" + event.getSession().getId() + "')");
}
// -------------------------------------------------------- Private Methods
/**
* Log a message to the servlet context application log.
*
* @param message Message to be logged
*/
private void log(String message) {
if (context != null)
context.log("SessionListener: " + message);
else
System.out.println("SessionListener: " + message);
}
/**
* Log a message and associated exception to the servlet context
* application log.
*
* @param message Message to be logged
* @param throwable Exception to be logged
*/
private void log(String message, Throwable throwable) {
if (context != null)
context.log("SessionListener: " + message, throwable);
else {
System.out.println("SessionListener: " + message);
throwable.printStackTrace(System.out);
}
}
}
严重: Error configuring application listener of class listeners.ContextListener
java.lang.ClassNotFoundException: listeners.ContextListener
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1354)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1200)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3769)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4335)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:759)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:739)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:524)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:919)
at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:882)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:491)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1137)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:310)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1021)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1013)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
at org.apache.catalina.core.StandardService.start(StandardService.java:450)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:709)
at org.apache.catalina.startup.Catalina.start(Catalina.java:551)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:287)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:412)
2008-7-27 23:42:48 org.apache.catalina.core.StandardContext listenerStart
严重: Error configuring application listener of class listeners.SessionListener
java.lang.ClassNotFoundException: listeners.SessionListener
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1354)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1200)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3769)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4335)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:759)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:739)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:524)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:919)
at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:882)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:491)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1137)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:310)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1021)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1013)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
at org.apache.catalina.core.StandardService.start(StandardService.java:450)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:709)
at org.apache.catalina.startup.Catalina.start(Catalina.java:551)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:287)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:412)
2008-7-27 23:42:48 org.apache.catalina.core.StandardContext listenerStart
严重: Skipped installing application listeners due to previous error(s)
2008-7-27 23:42:48 org.apache.catalina.core.StandardContext start
严重: Error listenerStart
2008-7-27 23:42:48 org.apache.catalina.core.StandardContext start
严重: Context [/examples] startup failed due to previous errors
2008-7-27 23:42:48 org.apache.coyote.http11.Http11AprProtocol start
信息: Starting Coyote HTTP/1.1 on http-8080
2008-7-27 23:42:49 org.apache.coyote.ajp.AjpAprProtocol start
信息: Starting Coyote AJP/1.3 on ajp-8009
2008-7-27 23:42:49 org.apache.catalina.startup.Catalina start
信息: Server startup in 7953 ms